【发布时间】:2019-11-29 10:23:36
【问题描述】:
我有一个 ViewController 具有以下结构((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) 被限制在 NavigationBar 的底部 (2) 和 superview 的底部 (1) - (当然还有必要的水平约束!)
UIView (3) 有以下约束:
- 所有子视图的前导约束为 0。
- 所有子视图的尾随约束为 0。
- UIButton 的底部间距为 24(应添加 一些 额外间距)
- 24 的顶部空间到最顶部的 UITextField(顶部间距)
- 0 到 superView (UIScrollView) 的顶部空间
- 0到superView(UIScrollView)的底部空间
- '等宽 - 负 32' 到 NavigationBar(所以 - 固定宽度)
在viewController的viewDidLoad中,我称之为:
registerForKeyboardWillShowNotification(self.scrollView)
registerForKeyboardWillHideNotification(self.scrollView)
其中registerForKeyboard...ShowNotification 是UIViewController 的扩展:
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)
}
}
}
但是,当键盘显示时,它并没有插入 scrollView(够了)。我调试了一下,是这样的:
- 普通键盘:
height = 216 - 带建议栏的常规键盘:
height = 260 - 带建议栏的 iPhone X 键盘:
height = 291
我首先虽然建议栏可能是问题,但事实并非如此。
在registerForKeyboardWillShowNotification 中,我将bottom: keyboardSize.height 更改为bottom: keyboardSize.height + 30,结果完全相同(我看到按钮的相同部分部分隐藏在键盘后面)。一旦我添加了 50 个或更多,它最终似乎会产生微小的差异。
- 我尝试了
keyboardDidShowNotification而不是keyboardWillShowNotification,但这并没有什么不同。 - 我尝试了
keyboardFrameBeginUserInfoKey而不是keyboardFrameEndUserInfoKey,但这并没有什么不同。
我在这里错过了什么?
【问题讨论】:
-
你的 UIView 约束是什么?
-
我编辑了问题并添加了 UIView 约束。
-
UIView 的高度呢?
-
这是从它的内容(TextFields / Button)派生的。因为它对那些有 24 的顶部和底部约束。
-
首先解决约束错误,我认为这是主要问题
标签: ios swift uiscrollview uikeyboard