Xcode 当我以编程方式更改约束时出现错误

Xcode giving error when I programmatically change constraints

我有一个 table 视图,我在 viewDidLoad() 方法中使用 4 个约束对其进行了初始化。我想稍后在代码中以编程方式更改 bottomAnchor,所以我将其保存为变量 bottomAnchor 然后我有另一个变量 keyboardBottomAnchor 用于更改的约束

这些是初始约束:

tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 50).isActive = true
tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
bottomAnchor = tableViewe.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant:  (-1) * card.cardHandleAreaHeight + -20)
bottomAnchor.isActive = true

基本上,我希望 table 视图在键盘打开时上升,在键盘关闭时下降。这是它的样子:

@objc func keyboardAppears(notification: Notification) {
        let userInfo = notification.userInfo
        keyboardFrame = userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! CGRect
       
        //this is the original constraint
        self.bottomConstraint.isActive = false
        //Here I make a new variable to save the new constraint
        keyboardBottomConstraint = tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -1 * keyboardFrame.height)
        keyboardBottomConstraint.isActive = true
}

@objc func keyboardDisappears(notification: Notification) {
        NSLayoutConstraint.deactivate([keyboardBottomConstraint])
        bottomConstraint.isActive = true
}

keyboardAppears 方法有效(table 视图在键盘显示时出现)但是 keyboardDisappears 方法给我一个 Unable to simultaneously satisfy constraints 错误(又名它是说 bottomConstraintkeyboardBottomConstraint 都处于活动状态)

关于为什么会发生这种情况有什么想法吗?

更新:

我使用了下面的 .constant(这有效,但只有在我第一次打开键盘时)

@objc func keyboardAppears(notification: Notification) {
        let userInfo = notification.userInfo
        var keyboardFrame = userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! CGRect
        
        bottomConstraint.constant = -1 * keyboardFrame.height
        tableView.scrollUp()
}

@objc func keyboardDisappears(notification: Notification) {
        returnOriginalConstraint()
}

func returnOriginalConstraint() {
        bottomAnchor.constant = (-1) * buttonCard.cardHandleAreaHeight + -20
}

//scrolling method
func scrollUp() {
        DispatchQueue.main.async {
            self.entrySpace.scrollToRow(at: IndexPath(row: self.data.count - 1, section: 0), at: .top, animated: true)
        }
}

Swift 5

不要停用约束,只需更改其常量值即可。

下面的代码我已经写好并测试过了,按你的喜好定制,一定会和你完美搭配!

import UIKit

class ViewController: UIViewController
{
    // MARK: Properties

    var tableView: UITableView!
    var tableBottomConstraint: NSLayoutConstraint!

    // MARK: View Controller Life Cycle

    override func viewDidLoad()
    {
        super.viewDidLoad()
        addKeyboardObservers()
        setupTableView()
    }

    deinit
    {
        removeKeyboardObservers()
    }

    // MARK: Methods

    private func addKeyboardObservers()
    {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillShow(notification:)),
                                               name: UIResponder.keyboardWillShowNotification,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillHide(notification:)),
                                               name: UIResponder.keyboardWillHideNotification,
                                               object: nil)
    }

    private func removeKeyboardObservers()
    {
        NotificationCenter.default.removeObserver(self,
                                                  name: UIResponder.keyboardWillShowNotification,
                                                  object: nil)

        NotificationCenter.default.removeObserver(self,
                                                  name: UIResponder.keyboardWillHideNotification,
                                                  object: nil)
    }

    private func setupTableView()
    {
        tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(tableView)

        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0).isActive = true

        tableBottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50.0)
        tableBottomConstraint.isActive = true
    }

    // MARK: Keyboard Handling

    @objc func keyboardWillShow(notification: Notification)
    {
        if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
        {
            tableBottomConstraint.constant = -1 * keyboardFrame.height
            loadViewIfNeeded()
        }
    }

    @objc func keyboardWillHide(notification: Notification)
    {
        tableBottomConstraint.constant = -50.0
        loadViewIfNeeded()
    }
}

Note: Do not forget to remove keyboard observers in deinit