安全地更改 NSLayoutConstraint 常量值
Safely change NSLayoutConstraint constant value
我的 UIView
对象有底部约束,我想更改它的值。在我这样做之后,视图确实显示正确,但是,我在控制台中看到错误日志;
[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:0x600003cbe670 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom + 306 (active)>",
"<NSLayoutConstraint:0x600003c8cbe0 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom - 10 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003cbe670 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom + 306 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
我的代码是:
private func setupKeyboard(){
keyboard.delegate = self
view.addSubview(keyboard)
keyboardBottomConstraint = keyboard.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: keyboard.expectedHeight())
keyboard.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
keyboardBottomConstraint.isActive = true
}
private func showKeyboard(){
let bottomOffset: CGFloat = 10
keyboardBottomConstraint.constant = -bottomOffset
}
所以,在我 setupKeyboard
之后没有错误,屏幕上也没有可见的视图,然后,在我调用 showKeyboard
之后它变得可见,但是出现错误。
将底部约束优先级值设置为高(750)
您可以自动使用 layoutIfNeeded 和 setNeedsLayout:
layoutIfNeeded 强制接收器在需要时立即布局其子视图。
假设您已经覆盖了 layoutSubviews,并且 UIKit 认为您的视图出于某种原因需要布局(例如,您在处理某些用户操作时调用了 setNeedsLayout)。然后,您的自定义 layoutSubviews 方法将立即被调用,而不是在常规 UIKit 运行 循环事件序列中通常被调用时被调用(在事件处理之后,但在 drawRect: 之前)。
您可能需要在单个 运行 循环中调用 layoutIfNeeded 的示例:
您调整了自定义视图的大小,其中包含具有自定义布局的 table 视图。设置 setNeedsLayout 以便稍后调用 layoutSubviews。
控制器对象要求 table 视图在处理用户事件时滚动到某个特定的单元格。
您的自定义视图对 layoutSubviews 中的 table 视图执行一些自定义大小调整,从而更改 table 视图大小。
问题是当控制器要求 table 视图滚动(第 2 步)时,table 视图的边界是陈旧的。更新后的边界只会在稍后(第 3 步)的 table 视图上设置。在 layoutSubviews 完成后,控制器希望 table 视图滚动到的内容可能实际上不可见。一个解决方案是让控制器在知道可能发生这种情况的情况下调用 layoutIfNeeded。
有错误/警告消息是关键:
(
"<NSLayoutConstraint:0x600003cbe670 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom + 306 (active)>",
"<NSLayoutConstraint:0x600003c8cbe0 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom - 10 (active)>"
)
如您所见,KeyboardView
有 两个 底部约束,它们不能同时有效。
根据 OP 的评论,setupKeyboard()
被无意中调用了两次,导致 2 个底部约束。
我的 UIView
对象有底部约束,我想更改它的值。在我这样做之后,视图确实显示正确,但是,我在控制台中看到错误日志;
[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:0x600003cbe670 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom + 306 (active)>",
"<NSLayoutConstraint:0x600003c8cbe0 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom - 10 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003cbe670 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom + 306 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
我的代码是:
private func setupKeyboard(){
keyboard.delegate = self
view.addSubview(keyboard)
keyboardBottomConstraint = keyboard.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: keyboard.expectedHeight())
keyboard.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
keyboardBottomConstraint.isActive = true
}
private func showKeyboard(){
let bottomOffset: CGFloat = 10
keyboardBottomConstraint.constant = -bottomOffset
}
所以,在我 setupKeyboard
之后没有错误,屏幕上也没有可见的视图,然后,在我调用 showKeyboard
之后它变得可见,但是出现错误。
将底部约束优先级值设置为高(750)
您可以自动使用 layoutIfNeeded 和 setNeedsLayout:
layoutIfNeeded 强制接收器在需要时立即布局其子视图。
假设您已经覆盖了 layoutSubviews,并且 UIKit 认为您的视图出于某种原因需要布局(例如,您在处理某些用户操作时调用了 setNeedsLayout)。然后,您的自定义 layoutSubviews 方法将立即被调用,而不是在常规 UIKit 运行 循环事件序列中通常被调用时被调用(在事件处理之后,但在 drawRect: 之前)。
您可能需要在单个 运行 循环中调用 layoutIfNeeded 的示例:
您调整了自定义视图的大小,其中包含具有自定义布局的 table 视图。设置 setNeedsLayout 以便稍后调用 layoutSubviews。 控制器对象要求 table 视图在处理用户事件时滚动到某个特定的单元格。 您的自定义视图对 layoutSubviews 中的 table 视图执行一些自定义大小调整,从而更改 table 视图大小。 问题是当控制器要求 table 视图滚动(第 2 步)时,table 视图的边界是陈旧的。更新后的边界只会在稍后(第 3 步)的 table 视图上设置。在 layoutSubviews 完成后,控制器希望 table 视图滚动到的内容可能实际上不可见。一个解决方案是让控制器在知道可能发生这种情况的情况下调用 layoutIfNeeded。
有错误/警告消息是关键:
(
"<NSLayoutConstraint:0x600003cbe670 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom + 306 (active)>",
"<NSLayoutConstraint:0x600003c8cbe0 PSBApp.KeyboardView:0x7fc5f760e010.bottom == UIView:0x7fc5f4503090.bottom - 10 (active)>"
)
如您所见,KeyboardView
有 两个 底部约束,它们不能同时有效。
根据 OP 的评论,setupKeyboard()
被无意中调用了两次,导致 2 个底部约束。