Xamarin.form Move up view when keyboard appear












0















I'm trying to build a Chat app UI, the idea of the Layout was pretty simple:



enter image description here



When the input bar is focused, keyboard show up and "push" up the chat bar, as it's a grid, the ListView will resize to fit the screen:



enter image description here



I update the input bar's margin to "push" it up:



NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
CGSize keyboardSize = result.RectangleFValue.Size;
if (Element != null){
Element.Margin = new Thickness(0, 0, 0,keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
}


And this is the result:
https://drive.google.com/file/d/1S9yQ6ks15BRH3hH0j_M8awpDJFRFitUi/view?usp=sharing



The view did push up and the ListView also resized as expected, however there are two issues that I had no idea how to solve it:




  1. How can I retain the ListView scroll position after resize?

  2. Lack of animation to push up the view


I have search over the web, tried IQKeyboardManager and KeyboardOverLap, The push up animation is nice and smooth, however strange things happened:



https://drive.google.com/file/d/1Zm0lMKB3wq07ve67wlcvLuNM_6Waad7R/view?usp=sharing




  1. Instead of resizing the ListView, this approach Push the entire ListView up, that I cannot see the first few items, of course the scroll bar can be scroll out of screen

  2. Extra strange spaces at the bottom of the ListView


Any help will be appreciated, thank you!



Solution:



  void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
{
NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
CGSize keyboardSize = result.RectangleFValue.Size;
if (Control != null)
{
int bottomMargin = 0;
var sa = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets;
bottomMargin = (int)sa.Bottom;

CGPoint offset = Control.ContentOffset;
var difference = keyboardSize.Height - bottomMargin;

if (Control.ContentSize.Height > Control.Frame.Height)
{
offset.Y += difference;
Control.SetContentOffset(offset, true);
}
else if (Control.ContentSize.Height + keyboardSize.Height > Control.Frame.Height)
{
offset.Y += Control.ContentSize.Height + keyboardSize.Height - Control.Frame.Height - bottomMargin;
Control.SetContentOffset(offset, true);
}

Control.ContentInset = new UIEdgeInsets(0, 0, difference, 0);
Control.ScrollIndicatorInsets = Control.ContentInset;

}

}

void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
{
if (Control != null)
{
Control.ContentInset = new UIEdgeInsets(0, 0, 0, 0);
Control.ScrollIndicatorInsets = new UIEdgeInsets(0, 0, 0, 0);
}

}









share|improve this question





























    0















    I'm trying to build a Chat app UI, the idea of the Layout was pretty simple:



    enter image description here



    When the input bar is focused, keyboard show up and "push" up the chat bar, as it's a grid, the ListView will resize to fit the screen:



    enter image description here



    I update the input bar's margin to "push" it up:



    NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
    CGSize keyboardSize = result.RectangleFValue.Size;
    if (Element != null){
    Element.Margin = new Thickness(0, 0, 0,keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
    }


    And this is the result:
    https://drive.google.com/file/d/1S9yQ6ks15BRH3hH0j_M8awpDJFRFitUi/view?usp=sharing



    The view did push up and the ListView also resized as expected, however there are two issues that I had no idea how to solve it:




    1. How can I retain the ListView scroll position after resize?

    2. Lack of animation to push up the view


    I have search over the web, tried IQKeyboardManager and KeyboardOverLap, The push up animation is nice and smooth, however strange things happened:



    https://drive.google.com/file/d/1Zm0lMKB3wq07ve67wlcvLuNM_6Waad7R/view?usp=sharing




    1. Instead of resizing the ListView, this approach Push the entire ListView up, that I cannot see the first few items, of course the scroll bar can be scroll out of screen

    2. Extra strange spaces at the bottom of the ListView


    Any help will be appreciated, thank you!



    Solution:



      void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
    {
    NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
    CGSize keyboardSize = result.RectangleFValue.Size;
    if (Control != null)
    {
    int bottomMargin = 0;
    var sa = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets;
    bottomMargin = (int)sa.Bottom;

    CGPoint offset = Control.ContentOffset;
    var difference = keyboardSize.Height - bottomMargin;

    if (Control.ContentSize.Height > Control.Frame.Height)
    {
    offset.Y += difference;
    Control.SetContentOffset(offset, true);
    }
    else if (Control.ContentSize.Height + keyboardSize.Height > Control.Frame.Height)
    {
    offset.Y += Control.ContentSize.Height + keyboardSize.Height - Control.Frame.Height - bottomMargin;
    Control.SetContentOffset(offset, true);
    }

    Control.ContentInset = new UIEdgeInsets(0, 0, difference, 0);
    Control.ScrollIndicatorInsets = Control.ContentInset;

    }

    }

    void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
    {
    if (Control != null)
    {
    Control.ContentInset = new UIEdgeInsets(0, 0, 0, 0);
    Control.ScrollIndicatorInsets = new UIEdgeInsets(0, 0, 0, 0);
    }

    }









    share|improve this question



























      0












      0








      0








      I'm trying to build a Chat app UI, the idea of the Layout was pretty simple:



      enter image description here



      When the input bar is focused, keyboard show up and "push" up the chat bar, as it's a grid, the ListView will resize to fit the screen:



      enter image description here



      I update the input bar's margin to "push" it up:



      NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
      CGSize keyboardSize = result.RectangleFValue.Size;
      if (Element != null){
      Element.Margin = new Thickness(0, 0, 0,keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
      }


      And this is the result:
      https://drive.google.com/file/d/1S9yQ6ks15BRH3hH0j_M8awpDJFRFitUi/view?usp=sharing



      The view did push up and the ListView also resized as expected, however there are two issues that I had no idea how to solve it:




      1. How can I retain the ListView scroll position after resize?

      2. Lack of animation to push up the view


      I have search over the web, tried IQKeyboardManager and KeyboardOverLap, The push up animation is nice and smooth, however strange things happened:



      https://drive.google.com/file/d/1Zm0lMKB3wq07ve67wlcvLuNM_6Waad7R/view?usp=sharing




      1. Instead of resizing the ListView, this approach Push the entire ListView up, that I cannot see the first few items, of course the scroll bar can be scroll out of screen

      2. Extra strange spaces at the bottom of the ListView


      Any help will be appreciated, thank you!



      Solution:



        void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
      {
      NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
      CGSize keyboardSize = result.RectangleFValue.Size;
      if (Control != null)
      {
      int bottomMargin = 0;
      var sa = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets;
      bottomMargin = (int)sa.Bottom;

      CGPoint offset = Control.ContentOffset;
      var difference = keyboardSize.Height - bottomMargin;

      if (Control.ContentSize.Height > Control.Frame.Height)
      {
      offset.Y += difference;
      Control.SetContentOffset(offset, true);
      }
      else if (Control.ContentSize.Height + keyboardSize.Height > Control.Frame.Height)
      {
      offset.Y += Control.ContentSize.Height + keyboardSize.Height - Control.Frame.Height - bottomMargin;
      Control.SetContentOffset(offset, true);
      }

      Control.ContentInset = new UIEdgeInsets(0, 0, difference, 0);
      Control.ScrollIndicatorInsets = Control.ContentInset;

      }

      }

      void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
      {
      if (Control != null)
      {
      Control.ContentInset = new UIEdgeInsets(0, 0, 0, 0);
      Control.ScrollIndicatorInsets = new UIEdgeInsets(0, 0, 0, 0);
      }

      }









      share|improve this question
















      I'm trying to build a Chat app UI, the idea of the Layout was pretty simple:



      enter image description here



      When the input bar is focused, keyboard show up and "push" up the chat bar, as it's a grid, the ListView will resize to fit the screen:



      enter image description here



      I update the input bar's margin to "push" it up:



      NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
      CGSize keyboardSize = result.RectangleFValue.Size;
      if (Element != null){
      Element.Margin = new Thickness(0, 0, 0,keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
      }


      And this is the result:
      https://drive.google.com/file/d/1S9yQ6ks15BRH3hH0j_M8awpDJFRFitUi/view?usp=sharing



      The view did push up and the ListView also resized as expected, however there are two issues that I had no idea how to solve it:




      1. How can I retain the ListView scroll position after resize?

      2. Lack of animation to push up the view


      I have search over the web, tried IQKeyboardManager and KeyboardOverLap, The push up animation is nice and smooth, however strange things happened:



      https://drive.google.com/file/d/1Zm0lMKB3wq07ve67wlcvLuNM_6Waad7R/view?usp=sharing




      1. Instead of resizing the ListView, this approach Push the entire ListView up, that I cannot see the first few items, of course the scroll bar can be scroll out of screen

      2. Extra strange spaces at the bottom of the ListView


      Any help will be appreciated, thank you!



      Solution:



        void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
      {
      NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
      CGSize keyboardSize = result.RectangleFValue.Size;
      if (Control != null)
      {
      int bottomMargin = 0;
      var sa = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets;
      bottomMargin = (int)sa.Bottom;

      CGPoint offset = Control.ContentOffset;
      var difference = keyboardSize.Height - bottomMargin;

      if (Control.ContentSize.Height > Control.Frame.Height)
      {
      offset.Y += difference;
      Control.SetContentOffset(offset, true);
      }
      else if (Control.ContentSize.Height + keyboardSize.Height > Control.Frame.Height)
      {
      offset.Y += Control.ContentSize.Height + keyboardSize.Height - Control.Frame.Height - bottomMargin;
      Control.SetContentOffset(offset, true);
      }

      Control.ContentInset = new UIEdgeInsets(0, 0, difference, 0);
      Control.ScrollIndicatorInsets = Control.ContentInset;

      }

      }

      void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
      {
      if (Control != null)
      {
      Control.ContentInset = new UIEdgeInsets(0, 0, 0, 0);
      Control.ScrollIndicatorInsets = new UIEdgeInsets(0, 0, 0, 0);
      }

      }






      ios xamarin






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 28 '18 at 3:58







      nathan1658

















      asked Nov 25 '18 at 11:51









      nathan1658nathan1658

      3117




      3117
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Solution:



          Refer the following code




          in iOS Custom Renderer




          protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
          {
          base.OnElementChanged(e);

          if(Control!=null)
          {
          Control.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag;

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillShow:"), new NSString("UIKeyboardWillShowNotification"), null);

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillHide:"), new NSString("UIKeyboardWillHideNotification"), null);

          }

          }


          [Export("KeyBoardWillShow:")]
          void KeyBoardWillShow(NSNotification note)
          {
          NSValue keyboardRect = (NSValue)note.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
          Control.ContentInset = new UIEdgeInsets(0,0, keyboardRect.RectangleFValue.Size.Height,0);
          }


          [Export("KeyBoardWillHide:")]
          void KeyBoardWillHide(NSNotification note)
          {
          Control.ContentInset = UIEdgeInsets.Zero;
          }





          share|improve this answer
























          • Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

            – nathan1658
            Nov 28 '18 at 3:43











          • I think I've solved it, thanks for your help!

            – nathan1658
            Nov 28 '18 at 3:58











          • Happy coding :)

            – Lucas Zhang - MSFT
            Nov 28 '18 at 6:00











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53467135%2fxamarin-form-move-up-view-when-keyboard-appear%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Solution:



          Refer the following code




          in iOS Custom Renderer




          protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
          {
          base.OnElementChanged(e);

          if(Control!=null)
          {
          Control.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag;

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillShow:"), new NSString("UIKeyboardWillShowNotification"), null);

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillHide:"), new NSString("UIKeyboardWillHideNotification"), null);

          }

          }


          [Export("KeyBoardWillShow:")]
          void KeyBoardWillShow(NSNotification note)
          {
          NSValue keyboardRect = (NSValue)note.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
          Control.ContentInset = new UIEdgeInsets(0,0, keyboardRect.RectangleFValue.Size.Height,0);
          }


          [Export("KeyBoardWillHide:")]
          void KeyBoardWillHide(NSNotification note)
          {
          Control.ContentInset = UIEdgeInsets.Zero;
          }





          share|improve this answer
























          • Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

            – nathan1658
            Nov 28 '18 at 3:43











          • I think I've solved it, thanks for your help!

            – nathan1658
            Nov 28 '18 at 3:58











          • Happy coding :)

            – Lucas Zhang - MSFT
            Nov 28 '18 at 6:00
















          1














          Solution:



          Refer the following code




          in iOS Custom Renderer




          protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
          {
          base.OnElementChanged(e);

          if(Control!=null)
          {
          Control.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag;

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillShow:"), new NSString("UIKeyboardWillShowNotification"), null);

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillHide:"), new NSString("UIKeyboardWillHideNotification"), null);

          }

          }


          [Export("KeyBoardWillShow:")]
          void KeyBoardWillShow(NSNotification note)
          {
          NSValue keyboardRect = (NSValue)note.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
          Control.ContentInset = new UIEdgeInsets(0,0, keyboardRect.RectangleFValue.Size.Height,0);
          }


          [Export("KeyBoardWillHide:")]
          void KeyBoardWillHide(NSNotification note)
          {
          Control.ContentInset = UIEdgeInsets.Zero;
          }





          share|improve this answer
























          • Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

            – nathan1658
            Nov 28 '18 at 3:43











          • I think I've solved it, thanks for your help!

            – nathan1658
            Nov 28 '18 at 3:58











          • Happy coding :)

            – Lucas Zhang - MSFT
            Nov 28 '18 at 6:00














          1












          1








          1







          Solution:



          Refer the following code




          in iOS Custom Renderer




          protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
          {
          base.OnElementChanged(e);

          if(Control!=null)
          {
          Control.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag;

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillShow:"), new NSString("UIKeyboardWillShowNotification"), null);

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillHide:"), new NSString("UIKeyboardWillHideNotification"), null);

          }

          }


          [Export("KeyBoardWillShow:")]
          void KeyBoardWillShow(NSNotification note)
          {
          NSValue keyboardRect = (NSValue)note.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
          Control.ContentInset = new UIEdgeInsets(0,0, keyboardRect.RectangleFValue.Size.Height,0);
          }


          [Export("KeyBoardWillHide:")]
          void KeyBoardWillHide(NSNotification note)
          {
          Control.ContentInset = UIEdgeInsets.Zero;
          }





          share|improve this answer













          Solution:



          Refer the following code




          in iOS Custom Renderer




          protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
          {
          base.OnElementChanged(e);

          if(Control!=null)
          {
          Control.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag;

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillShow:"), new NSString("UIKeyboardWillShowNotification"), null);

          NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("KeyBoardWillHide:"), new NSString("UIKeyboardWillHideNotification"), null);

          }

          }


          [Export("KeyBoardWillShow:")]
          void KeyBoardWillShow(NSNotification note)
          {
          NSValue keyboardRect = (NSValue)note.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
          Control.ContentInset = new UIEdgeInsets(0,0, keyboardRect.RectangleFValue.Size.Height,0);
          }


          [Export("KeyBoardWillHide:")]
          void KeyBoardWillHide(NSNotification note)
          {
          Control.ContentInset = UIEdgeInsets.Zero;
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 27 '18 at 8:25









          Lucas Zhang - MSFTLucas Zhang - MSFT

          2,5372210




          2,5372210













          • Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

            – nathan1658
            Nov 28 '18 at 3:43











          • I think I've solved it, thanks for your help!

            – nathan1658
            Nov 28 '18 at 3:58











          • Happy coding :)

            – Lucas Zhang - MSFT
            Nov 28 '18 at 6:00



















          • Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

            – nathan1658
            Nov 28 '18 at 3:43











          • I think I've solved it, thanks for your help!

            – nathan1658
            Nov 28 '18 at 3:58











          • Happy coding :)

            – Lucas Zhang - MSFT
            Nov 28 '18 at 6:00

















          Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

          – nathan1658
          Nov 28 '18 at 3:43





          Hi sorry for the late reply, your solution did push up the view nicely, but it also push up the message when there are only one or few messages, how can I handle that? Thanks

          – nathan1658
          Nov 28 '18 at 3:43













          I think I've solved it, thanks for your help!

          – nathan1658
          Nov 28 '18 at 3:58





          I think I've solved it, thanks for your help!

          – nathan1658
          Nov 28 '18 at 3:58













          Happy coding :)

          – Lucas Zhang - MSFT
          Nov 28 '18 at 6:00





          Happy coding :)

          – Lucas Zhang - MSFT
          Nov 28 '18 at 6:00




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53467135%2fxamarin-form-move-up-view-when-keyboard-appear%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Wiesbaden

          Marschland

          Dieringhausen