键盘显示和隐藏上的动画自动布局约束

Posted

技术标签:

【中文标题】键盘显示和隐藏上的动画自动布局约束【英文标题】:Animate autolayout constraints on keyboard show and hide 【发布时间】:2018-03-27 19:56:34 【问题描述】:

为了使这个简短而有趣,我尝试复制Facebook 登录屏幕的布局和动画。这里是:

我试图从简单的徽标开始。这是我设置logoContainerView的方法:

// Logo Container View
logoContainerView = UIImageView(image: #imageLiteral(resourceName: "icons8-golf-ball-64"))
logoContainerView.contentMode = .scaleAspectFit
logoContainerView.translatesAutoresizingMaskIntoConstraints = false
headerContainerView.addSubview(logoContainerView)
// Logo Container AutoLayout
logoContainerView.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
logoContainerView.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
logoContainerView.centerXAnchor.constraint(equalTo: headerContainerView.centerXAnchor).isActive = true
logoContainerView.centerYAnchor.constraint(equalTo: headerContainerView.centerYAnchor).isActive = true

现在我只是想让徽标在 xAxis 上移动并在显示键盘时调整约束大小。我正在使用以下代码执行此操作:

fileprivate func observeKeyboardNotifications() 
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: Notification.Name.UIKeyboardWillShow, object: nil)


@objc func keyboardWillShow() 
    logoContainerView.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
    logoContainerView.widthAnchor.constraint(equalToConstant: 50.0).isActive = true
    self.updateConstraintsIfNeeded()
    UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: 
        self.layoutIfNeeded()
    , completion: nil)

这确实有效。但是,我收到的似乎是warning,而不是error

2018-03-27 11:47:12.392282-0600 My App[4075:156614] [LayoutConstraints] 
Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x604000284380 UIImageView:0x7ffe84d13390.height == 100   (active)>",
    "<NSLayoutConstraint:0x604000291df0 UIImageView:0x7ffe84d13390.height == 50   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x604000284380 UIImageView:0x7ffe84d13390.height == 100   (active)>

我假设我收到了这个warning,因为我正在尝试通过激活它来设置logoContainerViews heightAnchor,而我之前已经设置了这个heightAnchor并使其处于活动状态。

我的最终问题是如何适当地解决这个问题?如何根据键盘是否显示以及何时不显示来设置约束?

感谢所有花时间回复和协助的人。

【问题讨论】:

我认为您应该在激活新约束之前停用现有约束 【参考方案1】:

问题是您当前向现有约束添加了约束,这会导致冲突

var hCon:NSLayoutConstraint!
var wCon:NSLayoutConstraint!

//

self.hCon = logoContainerView.heightAnchor.constraint(equalToConstant: 100.0) 
self.hCon.active = true
self.wCon = logoContainerView.widthAnchor.constraint(equalToConstant: 100.0) 
self.wCon.active = true

//

@objc func keyboardWillShow() 
   self.hCon.constant = 50 
   self.wCon.constant = 50
   UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: 
        self.layoutIfNeeded()
   , completion: nil)

【讨论】:

以上是关于键盘显示和隐藏上的动画自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

动画后自动布局约束不起作用[重复]

约束/自动布局栏隐藏,Xcode 6

最初不在屏幕上的动画和视图的自动布局?

自动布局、约束和动画

Swift UIView 自动布局和约束

键盘显示时更改自动布局常量