【问题标题】:Stop Keyboard From Hiding UITextField When Open打开时停止键盘隐藏 UITextField
【发布时间】:2020-05-26 21:09:03
【问题描述】:

寻找一种解决方案,以阻止 UITextField 在打开时被键盘隐藏,而不管 UITextField 在视图层次结构中的位置以及其他 UI 元素。

【问题讨论】:

    标签: ios xamarin keyboard uitextfield


    【解决方案1】:

    网上有很多解决方案可以调整您的视图,以便 UITextField 在出现时不会隐藏在键盘后面,但是我找不到“一刀切”的解决方案,因此不得不进行大量调整的答案,让我自己的。这是我想出的解决方案。希望它可以帮助某人:)

    首先,此解决方案假定您的“主要父级”或“顶级”视图是 UIScrollView 或后代(例如 UITableView 或 UICollectionView)。如果您的层次结构中没有 UIScrollView,这将不起作用,因为这是用于将 UITextField 滚动到位的内容。其他解决方案向您展示了如何滚动任何 UIView,但是当您考虑它时,如果您需要将 UITextField 滚动到位,那么您的视图应该可以滚动以阻止它离开屏幕。

    在下面创建扩展方法。这将搜索与给定查询匹配的子视图(等)的子视图,并将它们作为数组返回。我们稍后会用到它。

    public static UIView[] Find(this UIView view, Func<UIView, bool> query)
    {
        if (view == null)
            return null;
    
        var views = new List<UIView>();
    
        if (query.Invoke(view))
            views.Add(view);
    
        foreach (var subview in view.Subviews)
        {
            var foundViews = subview.Find(query);
    
            if (foundViews != null)
                views.AddRange(foundViews);
        }
    
        return views.ToArray();
    }
    

    将以下方法添加到您的 UIViewController。这会从视图层次结构中找到顶级 UIScrollView。 应该只有一个结果。

    private UIScrollView FindAdjustmentScrollView()
    {
        var scrollViews = View.Find(v => v is UIScrollView && v.FindSuperviewOfType(View, typeof(UIScrollView)) == null);
    
        return scrollViews.Length > 0 ? scrollViews[0] as UIScrollView : null;
    }
    

    添加以下事件处理程序。接下来我们将向观察者注册这些。

    private void Keyboard_Appear(NSNotification notification)
    {
        var firstResponder = View.Find(v => v.IsFirstResponder).FirstOrDefault();
    
        var scrollView = FindAdjustmentScrollView();
    
        if (firstResponder == null || scrollView == null || !(notification.UserInfo[UIKeyboard.FrameEndUserInfoKey] is NSValue value))
            return;
    
        var keyboardBounds = value.CGRectValue;
        var firstResponderAbsoluteFrame = firstResponder.Superview.ConvertRectToView(firstResponder.Frame, View);
    
        // This is how much of a gap you would like there to be between the bottom of the UITextField
        // and the top of the keyboard. Not mandatory but a nice touch in my experience.
        var offset = 8;
    
        var bottom = firstResponderAbsoluteFrame.Y + firstResponderAbsoluteFrame.Height + offset;
        var scrollAmount = keyboardBounds.Height - (scrollView.Frame.Size.Height - bottom);
    
        if (scrollAmount > 0)
            scrollView.SetContentOffset(0, scrollView.ContentOffset.Y + scrollAmount);
    }
    
    private void Keyboard_Disappear(NSNotification notification)
    {
        var firstResponder = View.Find(v => v.IsFirstResponder).FirstOrDefault();
    
        var scrollView = FindAdjustmentScrollView();
    
        if (firstResponder == null || scrollView == null)
            return;
    
        scrollView.SetContentOffset(0, 0);
    }
    

    将这 2 个字段添加到您的 UIViewController。通过保持对观察者的对象引用,我们可以在以后 UIViewController 不再可见时取消注册它们。

    private NSObject _keyboardWillShowObserver, _keyboardWillHideObserver;
    

    在 ViewWillAppear(或您注册事件处理程序的任何地方)中添加这两行。这些注册观察者并保留对象引用,以便我们稍后取消注册。

    _keyboardWillShowObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, Keyboard_Appear);
    _keyboardWillHideObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, Keyboard_Disappear);
    

    在 ViewWillDisappear(或您取消注册事件处理程序的任何地方)中添加这两行。这些从 UIViewController 中注销观察者,因此它们不再响应事件。

    NSNotificationCenter.DefaultCenter.RemoveObserver(_keyboardWillShowObserver);
    NSNotificationCenter.DefaultCenter.RemoveObserver(_keyboardWillHideObserver);
    

    澄清几点:

    • 当你的 UITextField 是一个向下很多层的子视图时(甚至 UITableViewCell 或 UICollectionViewCell)。
    • 此解决方案确实考虑了对键盘视图所做的任何修改。例如:如果您在键盘顶部添加“完成”按钮,则系统会计算该按钮。
    • 滚动调整是动画的。
    • 此解决方案确实适用于不同的方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-30
      • 2019-12-20
      • 2014-11-19
      • 1970-01-01
      • 2015-01-17
      • 2018-07-01
      相关资源
      最近更新 更多