出现键盘时以编程方式更新约束

Posted

技术标签:

【中文标题】出现键盘时以编程方式更新约束【英文标题】:Update constraints programmatically when keyboard appears 【发布时间】:2016-05-27 13:22:22 【问题描述】:

为了确保表格视图中的文本字段在启用键盘的情况下始终可见,我想向上移动表格视图以防它覆盖控件。 与以编程方式应用的自动布局结合使用时,我遇到了问题。

tableview的约束定义如下:

override func viewWillLayoutSubviews() 
    let views = ["tableView": tableView]

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[tableView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))

    let topConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
    self.view.addConstraint(topConstraint)

    bottomConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0)
    self.view.addConstraint(bottomConstraint)

要通过NSNotificationCenter 检测键盘,会调用以下方法(基于Getting keyboard size from userInfo in Swift 的答案):

func keyboardWillHide(sender: NSNotification) 
            bottomConstraint.constant = 0.0
            UIView.animateWithDuration(0.2, animations:  () -> Void in self.view.layoutIfNeeded() )
     

func keyboardWillShow(sender: NSNotification) 
    if let userInfo = sender.userInfo 
        if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height 
            self.view.layoutIfNeeded()

            bottomConstraint.constant = keyboardHeight
            UIView.animateWithDuration(0.2, animations:  () -> Void in
                self.view.layoutIfNeeded()
            )
        
    

但是,使用此代码,约束没有正确更新。而是出现以下错误:

Unable to simultaneously satisfy constraints.
…
(
    "<NSLayoutConstraint:0x109941b50 UITableView:0x1028ea600.bottom == UIView:0x10993b930.bottom>",
    "<NSLayoutConstraint:0x102417290 UITableView:0x1028ea600.bottom ==     UIView:0x10993b930.bottom + 271>"
)

为什么约束没有更新? viewWillLayoutSubviews 是这些约束的正确位置吗?

【问题讨论】:

尝试从代码中删除topConstraint 。我猜它会给出约束警告。 topConstraint 与 bottomConstraint 无关。警告仅在我尝试更新 bottomConstraint 时出现。 【参考方案1】:

如果您从界面生成器设置约束,那么您可以通过 ctrl + 拖动来消除任何约束。然后你可以管理它在键盘出现和隐藏时保持不变。

如果您以编程方式添加约束,那么您可以设置它的identifier,通过该标识符,您可以在任何地方使用该约束,并且可以在键盘出现或消失时管理常量。

如果你不想管理所有这些东西,那么你可以使用很棒的第三方库IQKeyboardmanager。

只需将其拖放到您的项目中即可!您无需执行任何操作,一切都会自动管理。

希望这会有所帮助:)

【讨论】:

所有约束都以编程方式定义并可直接访问(即相关约束“bottomConstraint”可以在没有标识符的情况下直接管理)。尽管该库是一个很好的建议(并且肯定会有所帮助),但我的主要问题是在视图初始化后我没有成功更新约束(似乎添加了新约束而不是更新,这导致了冲突)。我不仅在键盘外观的这种特定情况下遇到了这个问题,所以我很乐意解决这个问题。

以上是关于出现键盘时以编程方式更新约束的主要内容,如果未能解决你的问题,请参考以下文章

如何在显示旋转时以编程方式更改布局约束

在需要时以编程方式添加滚动

需要时以编程方式添加滚动

无法在运行时以编程方式影响闪烁控制

iOS 8 键盘扩展:出现呼叫栏时出现约束错误?

显示键盘时,WKWebView会出现约束问题