设置 UIScrollView 的内容键盘的内陷将显示通知无法正常工作



我有一个具有以下结构的视图控制器((x)指示级别(:

UIViewController    (1)
- NavigationBar   (2)
- UIScrollView    (2)
- UIView        (3)
- UITextField (4)
- UITextField (4)
- UITextField (4)
- UITextField (4)
- UIButton    (4)
  • 级别4的所有元素都垂直约束彼此,间距为 16。
  • 4级的第一个和最后一个元素被限制在UIView的(3(的顶部和底部。
  • UIView(3(被限制在UIScrollView(2(的顶部和底部。
  • UIScrollView (2( 被限制在导航栏的底部 (2( 和超级视图的底部 (1(
  • (当然,也有必要的水平约束!

UIView (3( 具有以下约束:

  • 对所有子视图的前导约束 0
  • 所有子视图的尾随约束为 0。
  • UIButton的底部空间为24(应添加一些额外的间距(
  • 顶部
  • 空间 24 到最顶层的 UIText字段(顶部间距(
  • 顶部空间 0 到 superView (UIScrollView(
  • 底部空间 0 到 superView (UIScrollView(
  • "等宽 - 减去 32"到导航栏(所以 - 固定宽度(

在 viewController 的viewDidLoad中,我称之为:

registerForKeyboardWillShowNotification(self.scrollView)
registerForKeyboardWillHideNotification(self.scrollView)

其中registerForKeyboard...ShowNotificationUIViewController的扩展:

extension UIViewController
{
/// Act when keyboard is shown, by adding contentInsets to the scrollView.
func registerForKeyboardWillShowNotification(_ scrollView: UIScrollView, usingBlock block: ((CGSize?) -> Void)? = nil)
{
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification,
object: nil, queue: nil)
{ notification in
let userInfo      = notification.userInfo!
let keyboardSize  = (userInfo[UIResponder.keyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue.size
let contentInsets = UIEdgeInsets(top: scrollView.contentInset.top,
left: scrollView.contentInset.left,
bottom: keyboardSize.height,
right: scrollView.contentInset.right)
scrollView.contentInset = contentInsets
block?(keyboardSize)
}
}
/// Act when keyboard is hidden, by removing contentInsets from the scrollView.
func registerForKeyboardWillHideNotification(_ scrollView: UIScrollView, usingBlock block: ((CGSize?) -> Void)? = nil)
{
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification,
object: nil, queue: nil)
{ notification in
let userInfo = notification.userInfo!
let keyboardSize = (userInfo[UIResponder.keyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue.size
let contentInsets = UIEdgeInsets(top: scrollView.contentInset.top,
left: scrollView.contentInset.left,
bottom: 0,
right: scrollView.contentInset.right)
scrollView.contentInset = contentInsets
block?(keyboardSize)
}
}
}

但是,当键盘显示时,它不会插入滚动视图(足够(。我调试了,情况是这样的:

  • 普通键盘:height = 216
  • 带建议栏的普通键盘:height = 260
  • 带建议栏的iPhone X键盘:height = 291

我首先认为建议栏可能是问题所在,但事实并非如此。

registerForKeyboardWillShowNotification年,我将bottom: keyboardSize.height更改为bottom: keyboardSize.height + 30,这给出了完全相同的结果(我看到按钮的相同部分部分隐藏在键盘后面(。一旦我添加 50 或更多,它似乎终于产生了一点不同。

  • 而不是keyboardWillShowNotification我尝试keyboardDidShowNotification,这没有区别。
  • 而不是keyboardFrameEndUserInfoKey我尝试keyboardFrameBeginUserInfoKey,这没有区别。

我在这里错过了什么?

不幸的是,我无法解决这个问题,我不确定为什么这不能按预期工作。

但是,我通过使用UIScrollView中的UIStackView获得了预期的行为。我用这篇文章作为参考。


用户界面布局

  • UIView控制器 (1(
    • 导航栏 (2(
    • UIScrollView (2(
    • UIStackView (3(
      • 用户界面扩展字段 (4(
      • 用户界面扩展字段 (4(
      • 用户界面扩展字段 (4(
      • 用户界面扩展字段 (4(
      • UI布顿 (4(

UIScrollView

  • ScrollView 的leadingtrailing被限制为16到超级视图。
  • ScrollView 的top在导航栏底部以0限制。
  • ScrollView 的bottom被限制为0到超级视图的底部。

UIStackView

  • StackView 的leadingtrailing在滚动视图中被限制为0
  • StackView 的宽度与滚动视图相等。
  • StackView 的topbottom被限制为24到滚动视图,以获得导航栏以及按钮和键盘之间的所需间距。
  • 堆栈视图设置为axis=verticalalignment=filldistribution=fillspacing=24

导航栏

导航栏是一个自定义类,其高度来自其内容。这没有设置高度约束,而是占位符高度 100。导航栏将填满整个屏幕。这可以通过删除占位符高度并添加任何具有低优先级(在本例中为1优先级(的高度约束来解决。


应用键盘内嵌的初始代码现在有效。

/// Act when keyboard is shown, by adding contentInsets to the scrollView.
func registerForKeyboardWillShowNotification(_ scrollView: UIScrollView, usingBlock block: ((CGSize?) -> Void)? = nil)
{
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification,
object: nil, queue: nil)
{ notification in
let userInfo      = notification.userInfo!
let keyboardSize  = (userInfo[UIResponder.keyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue.size
let contentInsets = UIEdgeInsets(top: scrollView.contentInset.top,
left: scrollView.contentInset.left,
bottom: keyboardSize.height,
right: scrollView.contentInset.right)
scrollView.contentInset = contentInsets
block?(keyboardSize)
}
}

相关内容

  • 没有找到相关文章

最新更新