How to deal with iOs keyboard overlapping entry when the page already has a scrollview in Xamarin Forms

前端 未结 2 2195
有刺的猬
有刺的猬 2021-02-14 09:02

I am having a problem regarding the keyboard on iOS. I am developing a chat page on Xamarin, cross platform, and this page has a scrollView which make possible to the user to sc

2条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-14 09:47

    One way you can deal with this is a custom page renderer that scrolls the whole page up when the keyboard appears.

    Here is some sample code to do this. I assume you would only want to do this on pages that have that need it, so first in the Forms PCL (Portable Class Library) project create an empty subclass of ContentPage e.g. called KeyboardInputContentPage (or whatever you like):

    public class KeyboardInputContentPage : ContentPage {}
    

    Then you inherit from the KeyboardInputContentPage for the actual page(s) that you need this functionality, in my test I called it TestKeyboardInputContentPage:

    public partial class TestKeyboardInputContentPage : KeyboardInputContentPage
    { 
        public TestKeyboardInputContentPage()
        {
            InitializeComponent();
        }
        //etc
    }
    

    And the custom page renderer code. This goes in the iOS app project:

    [assembly: ExportRenderer(typeof(KeyboardInputContentPage), typeof(ContentPageRenderer))]
    namespace MyAppName.iOS
    {
        public class ContentPageRenderer : PageRenderer
        {   
            private NSObject keyBoardWillShow;
            private NSObject keyBoardWillHide;
            private nfloat scrollAmout;
            private double animDuration;
            private UIViewAnimationCurve animCurve;
            private bool keyboardShowing;
    
            public override void ViewDidLoad()
            {
    
                base.ViewDidLoad();
    
                keyBoardWillShow = UIKeyboard.Notifications.ObserveWillShow(KeyboardWillShow);
    
                keyBoardWillHide = UIKeyboard.Notifications.ObserveWillHide(KeyboardWillHide);
            }
    
            void KeyboardWillShow(object sender, UIKeyboardEventArgs args)
            {
                if (!keyboardShowing)
                {
                    keyboardShowing = true;
                    animDuration = args.AnimationDuration;
                    animCurve = args.AnimationCurve;
    
                    var r = UIKeyboard.FrameBeginFromNotification(args.Notification);
                    scrollAmout = r.Height;
                    ScrollTheView(true);
                }
            }
    
            void KeyboardWillHide(object sender, UIKeyboardEventArgs args)
            {
                if (keyboardShowing)
                {
                    keyboardShowing = false;
                    animDuration = args.AnimationDuration;
                    animCurve = args.AnimationCurve;
    
                    var r = UIKeyboard.FrameBeginFromNotification(args.Notification);
                    scrollAmout = r.Height;
                    ScrollTheView(false);
                }
            }
    
            private void ScrollTheView(bool scale)
            {
                UIView.BeginAnimations(string.Empty, IntPtr.Zero);
                UIView.SetAnimationDuration(animDuration);
                UIView.SetAnimationCurve(animCurve);
    
                var frame = View.Frame;
    
                if (scale)
                    frame.Y -= scrollAmout;
                else
                    frame.Y += scrollAmout;
                View.Frame = frame;
                UIView.CommitAnimations();
            }
        }
    }
    

    Since this renderer actually scrolls the entire native page up and back down when the keyboard shows and hides, it should not matter how you layout the page in the Forms Xaml. All that matters is that your Forms page inherits from KeyboardInputContentPage.

    I hope this helps!

提交回复
热议问题