当我以编程方式更改约束时 Xcode 给出错误
Posted
技术标签:
【中文标题】当我以编程方式更改约束时 Xcode 给出错误【英文标题】:Xcode giving error when I programmatically change constraints 【发布时间】:2020-10-02 21:13:18 【问题描述】:我有一个表视图,我在 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
基本上,我希望表格视图在键盘打开时上升,在键盘关闭时返回。看起来是这样的:
@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
方法正在工作(当键盘显示时,表格视图会上升)但keyboardDisappears
方法给我一个Unable to simultaneously satisfy constraints
错误(也就是说bottomConstraint
和keyboardBottomConstraint
都是主动)
对为什么会发生这种情况有任何想法吗?
更新:
我使用了下面的.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)
【问题讨论】:
不需要创建新的约束。只需更新您已有的约束的constant
属性。您可以为这种变化设置动画。
感谢部分帮助:) 现在,它仅在我第一次使键盘出现/消失时起作用,但第二次不起作用。知道为什么吗?
当键盘消失的时候你有没有把常数设回去?如果没有看到您的新代码,我不能再说什么。您正在观察哪些通知?您是否设置了断点或日志语句以查看正在调用的函数?
不是您问题的答案,但如果您想避免使用键盘,我建议您使用IHKeyboardAvoiding
我在帖子中添加了带有常量的代码,如前所述,这仅在第一次有效?另外,我正在观察keyboardWillHideNotification
和keyboardWillShowNotification
【参考方案1】:
斯威夫特 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()
注意:不要忘记删除
deinit
中的键盘观察者
【讨论】:
谢谢 - 坚持了一段时间:) 如果可能的话,我有一个后续问题:我希望表格在上升时滚动到底部,所以我使用的是 tableView.scrollToRow。遗憾的是,它只能在第一次使用。 @green 首先,如果对您有帮助,请标记已接受的答案。关于您的问题,请提供更多详细信息和代码,我会帮助您。 标记为绿色!我只想添加self.entrySpace.scrollToRow(at: IndexPath(row: self.data.count - 1, section: 0), at: .top, animated: true)
以便在键盘出现时向上滚动内容 - 想知道如何将它放在上面?
是的,您应该将答案标记为已接受,并在您得到答案时投票。关于您的问题,请将您的代码放在keyboardWillShow
中,这样每当键盘出现时您就可以滚动。
谢谢,我会确保继续标记它。我仍然在滚动时遇到问题,所以我继续为它创建了另一个问题here。感谢您的帮助!以上是关于当我以编程方式更改约束时 Xcode 给出错误的主要内容,如果未能解决你的问题,请参考以下文章