我有一个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
)的顶部和底部。3
)受UIScrollView(2
)的顶部和底部约束。2
)被限制在NavigationBar的底部(2
)和超级视图的底部(1
) UIView(3
)具有以下约束:
在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
height = 291
尽管建议栏可能是我的问题,但我不是。
在registerForKeyboardWillShowNotification
中,我将bottom: keyboardSize.height
更改为bottom: keyboardSize.height + 30
,得到的结果完全相同(我看到按钮的相同部分部分隐藏在键盘后面)。一旦添加50或更多,它似乎最终会产生很小的变化。
keyboardWillShowNotification
我尝试过的keyboardDidShowNotification
,这没什么区别。keyboardFrameEndUserInfoKey
我尝试过的keyboardFrameBeginUserInfoKey
,这没什么区别。我在这里想念什么?
答案 0 :(得分:0)
不幸的是,我无法解决这个问题,我不确定为什么它不能按预期工作。
但是,我通过使用UIScrollView内的UIStackView得到了预期的行为。我以this article作为参考。
用户界面布局
UIScrollView
leading
和trailing
受 16 约束。 top
被导航栏底部的 0 约束。bottom
受到SuperView底部的 0 约束。 UIStackView
leading
和trailing
的滚动视图受 0 约束。top
和bottom
被 24 约束到滚动视图,以获取所需的NavigationBar间距以及按钮和键盘之间的间距。axis=vertical
,alignment=fill
,distribution=fill
,spacing=24
。导航栏
NavigationBar是一个自定义类,它从其内容派生其高度。它没有设置高度限制,但是占位符高度为100。NavigationBar将填满整个屏幕。通过删除占位符高度,并添加低优先级(在本例中为1
优先级)的 any 高度约束,可以解决此问题。
应用键盘嵌入的初始代码现在可以使用。
/// 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)
}
}