Xamarin form scroll editor

Using Xamarin Forms, view Xaml below.

<StackLayout VerticalOptions="FillAndExpand"> <Image x:Name="cameraImage" Source="camera.png" /> <Label Text="Describe the image" /> <Editor /> <Button Text="Save" /> </StackLayout> 

It displays the image, editor and save button. The image is in a 4x3 ratio and covers about a third of the available screen height. The editor is displayed below.

The problem is that the keyboard closes the editor in iOS. A common problem with iOS is usually.

Question: What is the way Xamarin Forms deals with this?

thanks

// Johan

+8
ios xamarin xamarin.forms
source share
6 answers

To get automatic scrolling for editors and posts using Xamarin.Forms, you usually just need to pack your View, in this case StackLayout, in a ScrollView:

 <ScrollView> <StackLayout VerticalOptions="FillAndExpand"> <Image x:Name="cameraImage" Source="camera.png" /> <Label Text="Describe the image" /> <Editor /> <Button Text="Save" /> </StackLayout> </ScrollView> 

The way it should work, but today (June 2014) there is an error preventing this from working fully with the Editor (it works well with Records). The problem is known and works.

[UPDATE 2014-11-20] The problem has been fixed and will be available in the next version of -pre XF 1.3

+6
source share

I just stumbled upon this question while writing a tiny chat application that basically contains a list of scrollable messages, a text entry and a submit button:

v0TQU.pngjVNWl.png

The problem with the previously published solution is that you will need to nest two types of scroll that are not recommended by the Xamarin.Forms Documentation . To prevent the keyboard from hiding the recording, I discovered the following hack:

I add a placeholder at the end of the main stack layout. Depending on whether the recording is focused (i.e. the keyboard is visible or not), the height of the placeholder is set to 0 or the height of the keyboard.

  // HACK: make entry visible when keyboard open var placeholder = new BoxView { HeightRequest = 0, }; entry.Focused += (sender, e) => placeholder.HeightRequest = 210; entry.Unfocused += (sender, e) => placeholder.HeightRequest = 0; Content = new StackLayout { VerticalOptions = LayoutOptions.Fill, Padding = 5, Children = { whoTable, messageScrollView, new StackLayout { Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.End, HeightRequest = 70, Children = { entry, sendButton, }, }, placeholder, }, }; 

Of course, this is not perfect. A particularly stiff keyboard height keyboard should be made more elegant. And probably you should only use it on iOS, not Android.

+10
source share

Sometimes you cannot put your main view in a scrollview, in cases where you can implement this by processing keyboard events in an iOS project and passing them to the Forms level. Android takes care of itself.

 using System; using Foundation; using UIKit; using RaiseKeyboard.iOS; [assembly: Xamarin.Forms.Dependency (typeof (KeyboardHelper))] namespace RaiseKeyboard.iOS { // Raises keyboard changed events containing the keyboard height and // whether the keyboard is becoming visible or not public class KeyboardHelper : IKeyboardHelper { public KeyboardHelper() { NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification); NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification); } public event EventHandler<KeyboardHelperEventArgs> KeyboardChanged; private void OnKeyboardNotification (NSNotification notification) { var visible = notification.Name == UIKeyboard.WillShowNotification; var keyboardFrame = visible ? UIKeyboard.FrameEndFromNotification(notification) : UIKeyboard.FrameBeginFromNotification(notification); if (KeyboardChanged != null) { KeyboardChanged (this, new KeyboardHelperEventArgs (visible, (float)keyboardFrame.Height)); } } } } 

Then at the form level:

 using System; using Xamarin.Forms; namespace RaiseKeyboard { // Provides static access to keyboard events public static class KeyboardHelper { private static IKeyboardHelper keyboardHelper = null; public static void Init() { if (keyboardHelper == null) { keyboardHelper = DependencyService.Get<IKeyboardHelper>(); } } public static event EventHandler<KeyboardHelperEventArgs> KeyboardChanged { add { Init(); keyboardHelper.KeyboardChanged += value; } remove { Init (); keyboardHelper.KeyboardChanged -= value; } } } public interface IKeyboardHelper { event EventHandler<KeyboardHelperEventArgs> KeyboardChanged; } public class KeyboardHelperEventArgs : EventArgs { public readonly bool Visible; public readonly float Height; public KeyboardHelperEventArgs(bool visible, float height) { Visible = visible; Height = height; } } } 

If you work in Stacklayout and want to raise the look above the keyboard, you can put a spacer with a height of 0 at the bottom of the stack. Then set it to the height of the keyboard when an event with a modified keyboard is raised.

 spacer.HeightRequest = e.Visible ? e.Height : 0; 

If you are working with Listview, you can handle this by translating your view into the amount by which it would be covered.

 bottomOffset = mainStack.Bounds.Bottom - textStack.Bounds.Bottom; textStack.TranslationY -= e.Visible ? e.Height - bottomOffset : bottomOffset - e.Height; 

Listviews need to be handled differently, since the height is automatically adjusted by Forms and correction is performed using the spacer results.

Example here: https://github.com/naturalistic/raisekeyboard

+5
source share

Expanding in response from @Falko, you can check out the iOS platform as Android handles this as expected initially.

I also added this to the page for a quick and dirty orientation through this answer .

 static bool IsPortrait(Page p) { return p.Width < p.Height; } 

In any case, I understand that Xamarin will add some solutions for this soon. Bye, though ...

 protected async void Message_Focused(object sender, EventArgs args) { if (Device.OS == TargetPlatform.iOS) { //TLR: still need a way to determine the iOS keyboard height first //until then, this is a functional hack if (IsPortrait(this)) { KeyboardSpacer.HeightRequest = 165; } else { KeyboardSpacer.HeightRequest = 114; } } } protected async void Message_Unfocused(object sender, EventArgs args) { if (Device.OS == TargetPlatform.iOS) { KeyboardSpacer.HeightRequest = 0; } } 
+1
source share

Be careful, raisekeyboard was just implemented for a single entry in the application, if you add a new entry, KeyboardHelper.KeyboardChanged is about to take off when the focus is in any entry.

 KeyboardHelper.KeyboardChanged += (sender, e) =>{ bottomOffset = this.ParentView.Bounds.Bottom - _editor.Bounds.Bottom; if (KeyboardStatus) _editor.TranslationY = e.Visible ? -(e.Height - bottomOffset) : 0; else _editor.TranslationY = 0; }; 
0
source share

Using ScrollView, as mentioned above, fixes the problem on iOS and partially fixes it on Android. To completely fix the problem in android, I found another simple and pleasant addition.

In android only, I replace the Xamarin form editor with the special TextEdit control for Android. Therefore, in my page constructor, I have the following code for Android.

 #if __ANDROID__ // I have editor defined in xaml named ReportTextEditor in stacklayout named MainStackLayout Editor sharedEditor = this.ReportTextEditor; MainStackLayout.Children.Remove(sharedEditor); //removing the ReportTextEditor which was defined in xaml EditText editText = new EditText(Forms.Context); //created android specific editor editText.InputType = InputTypes.ClassText | InputTypes.TextFlagAutoCorrect | InputTypes.TextFlagCapSentences | InputTypes.TextFlagMultiLine; //keyboard options, optional MainStackLayout.Children.Add(editText); //Added android specific edit text to my stack layout #endif 

You also need to add specific android namespaces.

 #if __ANDROID__ using Xamarin.Forms.Platform.Android; using Android.Widget; using Button = Xamarin.Forms.Button; using Android.Text; #endif 
0
source share

All Articles