约束不断变化但布局没有更新?

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 之类的方法:没有任何效果。布局未更新的原因可能是什么?我应该在什么地方调用 layoutupdate 方法?我一直在 self.view 上调用它们,但我什至不确定如果您尝试更新 table 视图单元格的布局,是否应该在视图上调用它。任何帮助将不胜感激。

我明白了。问题原来是约束本身。因为我访问错了。我将其定义为 saveButtonTrailingConstraint 但实际上我修改的是 saveButton 的宽度约束(显然不能设置动画)。而不是访问 saveButton.constraints[indexOfTrailingConstraint] 我应该定义 saveButton.superview!.constraints[indexOfTrailingConstraint] 因为约束属于超级视图而不是按钮本身。我想避免这个笨拙错误的最好方法是,如果您以编程方式修改约束,请始终仔细检查是否修改了正确的约束,因为它并不总是在第一眼看到。