Is there something in Xamarin for Auto-Scrolling when KeyBoard Show and Hide ?

MarcCayerMarcCayer Marc CayerUSMember

Is there something include in Xamarin for Scrolling the View with Keyboard when it Shows and Hides ?
Or should I have to do it on my own, like Obj-C.

Thx

Best Answer

«1

Answers

  • JohnMillerJohnMiller John Miller USForum Administrator, Xamarin Team Xamurai
    edited June 2013

    @MarcCayer,

    AFAIK, you have to usually handle this yourself. I know that Monotouch.Dialog does seem to handle this on its own though. There is a nice example pattern of a BaseController that gives keyboard notifications, which you can override in the derived classes to move your views in the Field Service example.

  • MarcCayerMarcCayer Marc Cayer USMember

    Any open source ?
    Trying to save time hehe

  • WouterDSWouterDS Wouter De Schuyter BEMember
    edited August 2013

    I'm looking for this implementation as well.
    Can't find it and can't make the above sample work.

    Anyone?

    Edit: this is how I do it now, but I wonder if there isn't a better way?

    screenshot

  • Marc-AntoineCayerMarc-AntoineCayer Marc-Antoine Cayer CAMember

    Unfortunately, No!

    But the hardwork is already done using Dialog.
    Otherwise, you have to do it on your own.

    Set Notifications :

    notificationKeyboardShow   = NSNotificationCenter.DefaultCenter.AddObserver ("UIKeyboardWillShowNotification", KeyboardUpNotification);
    
    notificationKeyboardHidden = NSNotificationCenter.DefaultCenter.AddObserver ("UIKeyboardWillHideNotification", KeyboardDownNotification);
    

    ... For my own, I am showing a UIScrollView, so on the Keyboard Notifications Listener, I increase / decrease the heigth of my scrollview, then scrolling with animation on the editing text label.

  • lpinholpinho Luis Pinho USMember

    Hi Guillermo,

    thanks for the great and complete example, you don't mention but I had to call from the RegisterForKeyboardNotifications to make this work from the subclass; do you call this method in any other way?

    Besides this everything else worked great, just had to tweak the offset value a bit and everything works great!!

    Thanks again for sharing your code,

    Luís Pinho

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    Hey @Ipinho you are right, this code was missing:

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
    
        //Only do this if required
        if (HandlesKeyboardNotifications()) {
            RegisterForKeyboardNotifications();
        }
    }
    

    Subclasses override HandlesKeyboardNotifications to activate it:

    public override bool HandlesKeyboardNotifications()
    {
        return true;
    }
    
  • LeighBowersLeighBowers Leigh Bowers GBMember

    Your post was very helpful Guillermo; especially once I found the BaseController class you were referring to: https://github.com/xamarin/prebuilt-apps/blob/master/FieldService/FieldService.iOS/Controllers/BaseController.cs

    One small change I did make was to ensure the calculated offset wouldn't cause the scroll view to reposition itself outside of the bounds of the view itself.

    I added this code after the "float offset = ..." line:

    // Ensure the new position offset is within the bounds of the scroll view
    if (relativeFrame.Y + offset > scrollView.Frame.Height)
        offset = keyboardHeight;
    
  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    Thanks @MilkyJoe, I did a small change some time ago to calculate the size of the overlapped frame of the scroll view bellow the keyboard, this change should avoid the issue that you are mentioning. I also moved all the UIScrollView related methods to a extension class. One thing left in the inker is to avoid moving the view if it's already fully visible. If anyone is interested I can post it to Gist.

  • LeighBowersLeighBowers Leigh Bowers GBMember

    I'm definitely interested in taking a look.

    And thanks again for your invaluable help!

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭
    edited December 2013

    @MilkyJoe here's the gist to the classes that I'm using. If you feel that something can be improved I'm open for suggestions.

    Cheers!

  • InitLiptonInitLipton Gerard Lawless USMember

    Really like this, works a charm @GuillermoGutierrez‌. Love when something just works

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    Thanks @InitLipton‌ , you just reminded me a small change in ScrollExtensions.cs that I didn't upload yet. Now the textfield won't be moved down. It was a little bit annoying that the textfield was completely visible and the scroll moved anyway. So feel free to update that class from the GIST.

    Cheers!

  • InitLiptonInitLipton Gerard Lawless USMember
    edited April 2014

    Hi @GuillermoGutierrez‌ Just having a small issue with the scrolling, I've played around with a few values but have made a complete mess of things. After I use my TextEdits and the keyboard pops up with the keyboard. After i lose part of the screen to the top. http://tinypic.com/r/11ierh2/8 http://tinypic.com/r/11ierh2/8

  • InitLiptonInitLipton Gerard Lawless USMember
    edited April 2014

    Sorry Figured it out there

    I just added the following lines to the BaseView

    var navHeight = 0f;
        if (NavigationController != null) 
        {
         navHeight =NavigationController.NavigationBar.Frame.Size.Height;
        }
        scrollView.RestoreScrollPosition(navHeight);
    

    Then in the ScrollView extension class

     public static void RestoreScrollPosition(this UIScrollView scrollView, float height = 0f)
            {
                scrollView.ContentInset = new UIEdgeInsets(height,0f,0f,0f);
                scrollView.ScrollIndicatorInsets = UIEdgeInsets.Zero;
            }
    

    Sorry for the silly question

  • KyleKowalskiKyleKowalski Kyle Kowalski USMember

    Thank you for the help @GuillermoGutierrez‌ however I am having an issue where the view tries to center on the textfield but it resets to the way it was before I saw you mentioned the issue but could you help me find where to put that change.

    Thanks

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    @InitLipton thanks for pointing that out, I was not taking into account the initial ContentInset of the scroll.

    @KyleKowalski‌ I'm not sure what's the issue that you are referring, can you provide a sample project? I will fix it if I can.

  • KyleKowalskiKyleKowalski Kyle Kowalski USMember

    figured it out wasn't increasing the bounds of the scroll view. Thanks for the help great tutorial

  • GMGGMG guillaume greffe AUMember

    Belated response but I have just written a free library called "LazyBind" which has has a built-in Keyboard avoiding feature. Just ensure you provide the UIViewController when you instantiate: new LazyBind(your_object, provide_controller_here)

    Library at http://components.xamarin.com/view/gmgsoftware

  • PavelPenkava.8634PavelPenkava.8634 Pavel Penkava CZMember

    Does anybody have the same problem with this solution on iOS 8 or is it just me? It seems like scrollView.ContentOffset is always 0,0 even after scrolling down manually :(

  • PruthviPruthvi Pruthvi USMember

    @Guillermo Thanks a lot for seamless Implementation. Your code worked really well.

  • ErikFAndersenErikFAndersen Erik F. Andersen DKMember ✭✭

    on iOS 8 and device (iPad4) I had to change

    OnKeyboardChanged (visible, landscape ? keyboardFrame.Width : keyboardFrame.Height);

    to

    OnKeyboardChanged (visible, keyboardFrame.Height);

  • NADIYADAMANINADIYADAMANI NADIYA DAMANI USMember

    This doesn't work for me when using a subview. I register the events but the methods never get called.

  • jstumyjstumy Jeffrey Stuij USUniversity

    @PavelPenkava I had the same issue! It turns out that Width and Height are flipped in the Frame for UIKeyboard (KeyboardFrame) in iOS8.

  • PavelPenkava.8634PavelPenkava.8634 Pavel Penkava CZMember

    @JeffreyStuij.1290: Exactly, but I think it was flipped just in emulator. I'm not sure about it right now.

  • pratik90pratik90 pratik kankhara INMember

    @PavelPenkava,@GuillermoGutiérrez, @InitLipton,@KyleKowalski‌
    Hi,

    I have created app using Xamain.Forms 1.3.4.

    I have textbox at the end of screen. When I tap on textbox the keyboard swipe up and content of screen gets up. While I am scrolling up and down the page content when keyboard is on I cannot able to see the top content and some sort of content I can see.

    Can you please help what to do here that can show whole page with all content even if keyboard is swipe up?

    Thanks

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    @ErikFAndersen On iOS 8 the UIWindow now rotates, so there's no need to use the width of the keyboard instead of the height when on landscape. I've updated the GIST with this change to also maintain iOS 7 compatibility.

    The result is something like this in ScrollExtensions class:

    var height = intersect.Height;
    if (!UIDevice.CurrentDevice.CheckSystemVersion(8, 0) && IsLandscape()) {
        height = intersect.Width;
    }
    scrollView.CenterView(viewToCenter, height, animated:animated);
    
  • GuiWaltrickeGuiWaltricke Guilherme Waltricke BRMember ✭✭

    @GuillermoGutierrez

    your classses only works in Mono project? unfield project shows many errors here....

    do you know about compatibility with Unfield projects? i need only to make my view a child of yours ParentViewController.Keyboard exactly?

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    @Guilherme.W Unified API migration is pretty straight forward, just change the namespaces and fix the errors. I've updated the GIST with the migration prepared.

  • GuiWaltrickeGuiWaltricke Guilherme Waltricke BRMember ✭✭

    @GuillermoGutierrez

    I tried and the view was not scrolled no shows errors but an alert:

    Here is my C# file...

    i have a UIViewController > UIView > UISCrollView > UIView(contentView)

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    @Guilherme.W Those are warnings, if it's not working the problem must be elsewhere. That code was prepared to be used as a parent view controller. Child classes could set those values to customize the behavior of the scroll. I think that the variable names and the comments are pretty self-explanatory.

    Try to debug the OnKeyboardChanged method to see why it's not changing the scroll position.

  • GuiWaltrickeGuiWaltricke Guilherme Waltricke BRMember ✭✭

    @GuillermoGutierrez

    Now it works pretty good, the problem was that in your GIST HandlesKeyboardNotifications() was false, i changed to true and it worked! thanks

  • SpyrosBoutsisSpyrosBoutsis Spyros Boutsis USMember ✭✭

    Hi,

    I'm facing the same problem that @NADIYADAMANI reported. In iOS 8, the handlers I register for UIKeyboard.WillHideNotification and UIKeyboard.WillShowNotification are never called. I also tried UIKeyboard.WillChangeFrameNotification, same thing. Any ideas?

    I'm not using the designer and/or auto layout. My views are all built manually through code.

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    @SpyrosBoutsis The code is pretty self-explanatory (see the comments):

    /// <summary>
    /// Call this method from constructor, ViewDidLoad or ViewWillAppear to enable keyboard handling in the main partial class
    /// </summary>
    void InitKeyboardHandling()
    
    
    /// <summary>
    /// Override point for subclasses, return true if you want to handle keyboard notifications
    /// to center the active responder in the scroll above the keyboard when it appears
    /// </summary>
    public virtual bool HandlesKeyboardNotifications() {
        return false;
    }
    

    Have you added a call to InitKeyboardHandling in ViewDidLoad or ViewWillAppear methods?
    Have you overridden HandlesKeyboardNotifications to return true in the view controllers that require keyboard notifications?

    Remember that you can modify the code to fit your needs. I just shared what I'm using in my projects.

  • SpyrosBoutsisSpyrosBoutsis Spyros Boutsis USMember ✭✭

    Thanks for your reply. I used your code in the past and it worked fine under iOS 7, so I thought my problem had to do with some underlying change in iOS 8.

    Well, it turns out that it was just the iOS 8 simulator not showing the soft keyboard by default (I had to explicitly enable it). I spent two days trying to figure out why the keyboard does not show up and why I'm not getting any notifications...

    Thanks anyway!

  • GuillermoGutierrezGuillermoGutierrez Guillermo Gutiérrez ESMember ✭✭✭

    @SpyrosBoutsis You can toggle Software / Hardware keyboards in the new simulator by pressing ⌘+K.

  • ChakravarthiChakravarthi Chakravarthi Vantipalli INMember
    edited May 2015

    hi
    i used the above code for autoscrolling when keyboard hide and show.

    My problem is after the key board appears the first half in the scrollview is interacting to the user , the below half in the scroll view is not interacting to the user. Nothing is happening in the below half when user touches

    Note : i got this problem only when keyboard appears.

    Please tell me a solution for this.....

  • MoussaElChaterMoussaElChater Moussa El Chater USMember

    @GuillermoGutierrez‌ Works like a charm!! Thanks!!

  • GeorgeTaskosGeorgeTaskos George Taskos USMember ✭✭

    Still can't find a good generic solution (if exists) that it will work with Auto Layout. All the solutions for Xamarin and iOS Obejctive-C don't apply today since you most probably will use Auto Layout.

«1
Sign In or Register to comment.