NSLayoutConstraint的不满意约束已通过编程方式更改-Swift

问题描述

我正在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元素(和支持代码) 一次 。如果/当再次遇到约束冲突时,您将确切知道哪里出了错。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...