【问题标题】:Xamarin.form Move up view when keyboard appearXamarin.form 键盘出现时上移视图
【发布时间】:2018-11-28 11:58:59
【问题描述】:

我正在尝试构建一个聊天应用程序 UI,布局的想法非常简单:

当输入栏获得焦点时,键盘会出现并“推动”聊天栏,因为它是一个网格,ListView 将调整大小以适应屏幕:

我将输入栏的边距更新为“向上推”:

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
}

结果如下: https://drive.google.com/file/d/1S9yQ6ks15BRH3hH0j_M8awpDJFRFitUi/view?usp=sharing

视图确实向上推,ListView 也按预期调整了大小,但是有两个问题我不知道如何解决:

  1. 如何在调整大小后保留 ListView 的滚动位置?
  2. 缺乏向上推视图的动画

我在网上搜索过,试过 IQKeyboardManager 和 KeyboardOverLap,俯卧撑动画很好很流畅,但是奇怪的事情发生了:

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

  1. 这种方法不是调整ListView的大小,而是将整个ListView向上推,看不到前几项,当然滚动条可以滚动出屏幕
  2. ListView 底部有多余的奇怪空格

任何帮助将不胜感激,谢谢!

解决方案:

  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


    【解决方案1】:

    解决方案:

    参考以下代码

    在 iOS 自定义渲染器中

    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;
    } 
    

    【讨论】:

    • 您好,很抱歉回复晚了,您的解决方案确实很好地推送了视图,但是当只有一条或几条消息时它也会推送消息,我该如何处理?谢谢
    • 快乐编码:)
    猜你喜欢
    • 2018-05-21
    • 2010-12-19
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 2015-11-29
    • 2012-07-25
    相关资源
    最近更新 更多