约束不断变化但布局没有更新?
Constraint constant changes but layout doesn't get updated?
我有一个奇怪的问题:在我的 table 视图中,我想在 UISlider
被修改时更新单个单元格(值更改控制事件)。在滑块的值发生变化的那一刻,我想将一个按钮动画化到单元格中(从右侧滑入)。我将按钮约束的常量设置为 -50 以确保它在默认情况下不可见,并且当滑块的值发生变化时,将调用一个方法来更新 table 视图,因此 cellForRowAtIndexPath
被调用再次为我 table 中的所有单元格。简化后看起来像这样:
func valueChanged(sender:UISlider) {
// Reload table view
self.myTableView.reloadData()
// Let table view know the value of the slider got modified
self.didChangeValueOfSlider = true
}
在 cellForRowAtIndexPath
中,我使用自定义 selectedCellIndexPath
变量跟踪更改了哪个单元格的滑块。当 table 视图到达已修改的单元格时:它运行以下代码:
// Check if cell is selected
if indexPath == self.selectedCellIndexPath {
// Check if value of slider was changed
if self.didChangeValueOfSlider == true {
// Value was changed: set constraint back to default
saveButtonTrailingConstraint.constant = CGFloat(15)
self.view.setNeedsUpdateConstraints()
self.view.updateConstraintsIfNeeded()
// Reset slider update status
self.didChangeValueOfSlider = false
}
}
调用那些 setNeedsUpdateConstraints()
和 updateConstraintsIfNeeded()
可能有点矫枉过正或没有必要,但请注意,这是我第 15 次尝试实际让视图显示更新后的布局。在上面的代码完成 运行 并且一切正常后,我使用断点来确认常量实际上发生了变化。我唯一无法工作的是更新部分。我试过 UIView.animateWithDuration
使变化动起来,我试过 table 视图的 layoutIfNeeded()
和 beginUpdates()
和 endUpdates
之类的方法:没有任何效果。布局未更新的原因可能是什么?我应该在什么地方调用 layout
和 update
方法?我一直在 self.view
上调用它们,但我什至不确定如果您尝试更新 table 视图单元格的布局,是否应该在视图上调用它。任何帮助将不胜感激。
我明白了。问题原来是约束本身。因为我访问错了。我将其定义为 saveButtonTrailingConstraint
但实际上我修改的是 saveButton
的宽度约束(显然不能设置动画)。而不是访问 saveButton.constraints[indexOfTrailingConstraint]
我应该定义 saveButton.superview!.constraints[indexOfTrailingConstraint]
因为约束属于超级视图而不是按钮本身。我想避免这个笨拙错误的最好方法是,如果您以编程方式修改约束,请始终仔细检查是否修改了正确的约束,因为它并不总是在第一眼看到。
我有一个奇怪的问题:在我的 table 视图中,我想在 UISlider
被修改时更新单个单元格(值更改控制事件)。在滑块的值发生变化的那一刻,我想将一个按钮动画化到单元格中(从右侧滑入)。我将按钮约束的常量设置为 -50 以确保它在默认情况下不可见,并且当滑块的值发生变化时,将调用一个方法来更新 table 视图,因此 cellForRowAtIndexPath
被调用再次为我 table 中的所有单元格。简化后看起来像这样:
func valueChanged(sender:UISlider) {
// Reload table view
self.myTableView.reloadData()
// Let table view know the value of the slider got modified
self.didChangeValueOfSlider = true
}
在 cellForRowAtIndexPath
中,我使用自定义 selectedCellIndexPath
变量跟踪更改了哪个单元格的滑块。当 table 视图到达已修改的单元格时:它运行以下代码:
// Check if cell is selected
if indexPath == self.selectedCellIndexPath {
// Check if value of slider was changed
if self.didChangeValueOfSlider == true {
// Value was changed: set constraint back to default
saveButtonTrailingConstraint.constant = CGFloat(15)
self.view.setNeedsUpdateConstraints()
self.view.updateConstraintsIfNeeded()
// Reset slider update status
self.didChangeValueOfSlider = false
}
}
调用那些 setNeedsUpdateConstraints()
和 updateConstraintsIfNeeded()
可能有点矫枉过正或没有必要,但请注意,这是我第 15 次尝试实际让视图显示更新后的布局。在上面的代码完成 运行 并且一切正常后,我使用断点来确认常量实际上发生了变化。我唯一无法工作的是更新部分。我试过 UIView.animateWithDuration
使变化动起来,我试过 table 视图的 layoutIfNeeded()
和 beginUpdates()
和 endUpdates
之类的方法:没有任何效果。布局未更新的原因可能是什么?我应该在什么地方调用 layout
和 update
方法?我一直在 self.view
上调用它们,但我什至不确定如果您尝试更新 table 视图单元格的布局,是否应该在视图上调用它。任何帮助将不胜感激。
我明白了。问题原来是约束本身。因为我访问错了。我将其定义为 saveButtonTrailingConstraint
但实际上我修改的是 saveButton
的宽度约束(显然不能设置动画)。而不是访问 saveButton.constraints[indexOfTrailingConstraint]
我应该定义 saveButton.superview!.constraints[indexOfTrailingConstraint]
因为约束属于超级视图而不是按钮本身。我想避免这个笨拙错误的最好方法是,如果您以编程方式修改约束,请始终仔细检查是否修改了正确的约束,因为它并不总是在第一眼看到。