Swift 通过更改约束常量设置视图动画

Swift 通过更改约束常量设置视图动画,swift,animation,autolayout,nslayoutconstraint,Swift,Animation,Autolayout,Nslayoutconstraint,我有一个日期选择器,我想通过将其“顶部约束”更改为“超级视图顶部”,从底部设置视图内外的动画 我设置了一个IBOutlet,在viewDidLoad上,我可以更改约束常量 但是,通过iAction,我尝试将常量设置为另一个值,但这不会持续 @IBAction func showDatePicker() { UIView.animateWithDuration(0.25, animations: { () -> Void in self.datePicker

我有一个日期选择器,我想通过将其“顶部约束”更改为“超级视图顶部”,从底部设置视图内外的动画

我设置了一个IBOutlet,在viewDidLoad上,我可以更改约束常量

但是,通过iAction,我尝试将常量设置为另一个值,但这不会持续

@IBAction func showDatePicker() {
    UIView.animateWithDuration(0.25, animations: {
      () -> Void in
      self.datePickerTopConstraint.constant = self.view.frame.size.height - self.datePicker.frame.size.height // Doesn't persist
      self.view.layoutIfNeeded()
    })
  }
似乎我可以逆转这一点,让日期选择器出现在视图中(在viewDidLoad中)并在视图外设置动画,但不能让日期选择器出现在视图外(如上面的示例中)并在视图内设置动画。我错过了什么

编辑

通过将top constraint常量设置为超级视图的高度I(出于某些原因,我不明白),还可以将日期选择器的高度设置为0,从而使showDatePicker中的减法变得毫无意义。

尝试以下方法:

func showDatePicker() {
    self.view.layoutIfNeeded()
    UIView.animateWithDuration(0.25, animations: {
      () -> Void in
      self.datePickerTopConstraint.constant = self.view.frame.size.height - self.datePicker.frame.size.height // Doesn't persist
      self.view.layoutIfNeeded()
    })
  }

需要在动画块之前和块中调用layoutIfNeeded。现在,它正在正确计算视图。就像我说的,在viewDidLoad中设置任何约束也是没有意义的,如果您要在任何地方执行,那么在viewDidLoad中执行将出现。视图尚未在viewDidLoad中完成设置,因此没有可用于正确设置的约束。在动画块之前调用layoutIfNeeded可以修复此错误,您仍然需要它,这样它将来也可以正确计算。

重新构造代码,以便在按钮的方法中,通过首先计算常量的新值,然后调用动画来工作。将高度计算拉入到它自己的函数中。我认为,
self.datePicker.frame.size.height
不存在,结果为0,但我会使用调试器检查这一点

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    datePickerTopConstraint.constant = constantForDatePickerViewHeightConstraint()
    view.setNeedsLayout()

}


@IBAction func showDatePicker(button: UIButton) {

    // Check constraint constant
    if datePickerTopConstraint.constant == self.view.frame.size.height {

        // Date picker is NOT visible
        datePickerTopConstraint.constant = constantForDatePickerViewHeightConstraint()

    } else {
        // Date picker is visible
        datePickerTopConstraint.constant = self.view.frame.size.height
    }


    UIView.animateWithDuration(0.25,
        animations: {() -> Void in
        self.view.layoutIfNeeded()
    })
}

private func constantForDateOPickerViewHeightConstraint() -> CGFloat {

    var value : CGFloat = 200.0

    // Workout value you want to as the constant for the constraint.

    return value
}

我觉得你读我的问题有点太快了视图的移动应在按下按钮时完成。初始约束在viewDidLoadAdding self.view.layoutifneedd()中设置得很好,在动画调用之前不会影响我的情况(我已经验证过),因为布局没有挂起的更改,但您是对的,通常这样做是明智的。另外,我认为您错误地认为视图没有在viewDidLoad中完成。我已经检查了调试器中的所有内容,并确保所有数据都符合我的要求。即使约束IBOutlet设置正确,日期选择器的开始位置也可以设置在我想要的任何位置。将约束的初始设置移动到ViewWillAspect不会更改结果:(如果您发送给我一个具有相同故事板和视图控制器代码的项目,我很乐意看一看。Thx,但无需担心。视图高度的挤压是罪魁祸首。:)您是对的,而
self.datePicker
确实存在,如果我将其“顶部约束常量”设置为其父视图的高度,则其“高度”为零。就好像我这样做是在压扁风景。谢谢你为我指明了正确的方向!:)
po self.datePicker.frame
showDatePicker
中生成
(原点=(x=16,y=667),大小=(宽度=343,高度=0))
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    datePickerTopConstraint.constant = constantForDatePickerViewHeightConstraint()
    view.setNeedsLayout()

}


@IBAction func showDatePicker(button: UIButton) {

    // Check constraint constant
    if datePickerTopConstraint.constant == self.view.frame.size.height {

        // Date picker is NOT visible
        datePickerTopConstraint.constant = constantForDatePickerViewHeightConstraint()

    } else {
        // Date picker is visible
        datePickerTopConstraint.constant = self.view.frame.size.height
    }


    UIView.animateWithDuration(0.25,
        animations: {() -> Void in
        self.view.layoutIfNeeded()
    })
}

private func constantForDateOPickerViewHeightConstraint() -> CGFloat {

    var value : CGFloat = 200.0

    // Workout value you want to as the constant for the constraint.

    return value
}