问题描述
我正在viewDidLoad中设置一个约束,然后在键盘显示时更改其常数。 这是初始设置
bottomConstraint = NSLayoutConstraint(item: bottomBar,attribute: .bottom,relatedBy: .equal,toItem: view,multiplier: 1,constant: 0)
view.addConstraint(bottomConstraint)
@objc func handleKeyboardNotification(notification: NSNotification){
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
let isKeyboardShowing = notification.name == UIResponder.keyboardWillShowNotification
bottomConstraint?.constant = isKeyboardShowing ? -keyboardHeight : 0
UIView.animate(withDuration:0.1,delay: 0,options: .curveEaSEOut,animations: {
self.view.layoutIfNeeded()
},completion: {(completed) in
})
}
}
这很有趣,因为我只更改常量而不添加其他约束。不过,我在控制台中收到此警告:
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:0x282ae4ff0 UIView:0x109f11110.bottom == UIView:0x109f13240.bottom (active)>","<NSLayoutConstraint:0x282ae8050 UIView:0x109f11110.bottom == UIView:0x109f13240.bottom - 291 (active)>"
)
基本上,这说明我所拥有的限制条件对togheter并不适用。 我不知道我在做什么错。
let bottomBar:UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
在ViewdidLoad()
view.addSubview(bottomBar)
bottomBar.addSubview(fontView)
bottomBar.addSubview(colorPicker)
fontView.pin(to: bottomBar)
colorPicker.pin(to: bottomBar)
func setUpConstraints(){
NSLayoutConstraint.activate([
bottomBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),bottomBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),bottomBar.heightAnchor.constraint(equalToConstant: 70),])
}
解决方法
您没有提供足够的信息,因此有必要猜测。这是一个猜测。当你说:
fontView.pin(to: bottomBar)
colorPicker.pin(to: bottomBar)
您创建两个 bottomBar
底部约束。当你说:
bottomConstraint = NSLayoutConstraint(item: bottomBar,attribute: .bottom,relatedBy: .equal,toItem: view,multiplier: 1,constant: 0)
view.addConstraint(bottomConstraint)
您创建第三个底部约束。
然后当你说
bottomConstraint?.constant = isKeyboardShowing ? -keyboardHeight : 0
您更改了一个底部约束,但没有其他约束。也许是造成冲突的原因。
另一种可能性是,也许您以某种未显示给我们的方式两次致电view.addConstraint
。同样,这意味着您要更改一个底部约束,而不能更改另一个。
尝试让您更轻松...
从简单开始。
此代码在顶部附近创建一个文本字段,在底部创建一个红色的“ bottomBar”视图。当键盘显示或隐藏时,bottomBar的底部约束常量将更新(在视图上的任意位置点击以关闭键盘):
class ConstraintTestViewController: UIViewController {
let bottomBar = UIView()
var bottomConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// add a text field
let tf = UITextField()
tf.borderStyle = .roundedRect
tf.translatesAutoresizingMaskIntoConstraints = false
bottomBar.translatesAutoresizingMaskIntoConstraints = false
bottomBar.backgroundColor = .red
view.addSubview(tf)
view.addSubview(bottomBar)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain text field 80-pts from Top,Width: 240,centerX
tf.topAnchor.constraint(equalTo: g.topAnchor,constant: 80.0),tf.widthAnchor.constraint(equalToConstant: 240.0),tf.centerXAnchor.constraint(equalTo: g.centerXAnchor),// constrain bottomBar Leading and Trailing,Height: 70-pts
bottomBar.leadingAnchor.constraint(equalTo: g.leadingAnchor),bottomBar.trailingAnchor.constraint(equalTo: g.trailingAnchor),bottomBar.heightAnchor.constraint(equalToConstant: 70.0),])
// create and add the bottom constraint
bottomConstraint = NSLayoutConstraint(item: bottomBar,constant: 0)
view.addConstraint(bottomConstraint)
// or,use more modern syntax...
//bottomConstraint = bottomBar.bottomAnchor.constraint(equalTo: g.bottomAnchor)
//bottomConstraint.isActive = true
// keyboard show/hide notifications
NotificationCenter.default.addObserver(self,selector: #selector(self.handleKeyboardNotification(notification:)),name: UIResponder.keyboardWillShowNotification,object: nil)
NotificationCenter.default.addObserver(self,name: UIResponder.keyboardWillHideNotification,object: nil)
// add a "tap on the view to dismiss the keyboard" gesture
let t = UITapGestureRecognizer(target: self,action: #selector(self.didTap(_:)))
view.addGestureRecognizer(t)
}
@objc func handleKeyboardNotification(notification: NSNotification){
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
let isKeyboardShowing = notification.name == UIResponder.keyboardWillShowNotification
bottomConstraint.constant = isKeyboardShowing ? -keyboardHeight : 0
UIView.animate(withDuration:0.1,delay: 0,options: .curveEaseOut,animations: {
self.view.layoutIfNeeded()
},completion: {(completed) in
})
}
}
@objc func didTap(_ g: UITapGestureRecognizer) -> Void {
view.endEditing(true)
}
}
如果运行时没有自动布局错误/警告(它将),则开始一次添加其他UI元素(和支持代码) 一次 。如果/当再次遇到约束冲突时,您将确切知道哪里出了错。