Skip to content

Animating Constraints

CoderYoung edited this page Jan 13, 2016 · 1 revision

###最近看了 Raywenderlich 的 《iOS Animations by Tutorials》,来做个读书笔记,感兴趣请支持正版。

Chapter 7: Animating Constraints

上一章节学习了如何在IB创建autolayout约束,使用了autolayout后,无法再通过修改view的frame或者center属性来创建动画,这一章来学习如何使用autolayout动画。

Animating Interface Builder constraints

autolayout动画其实就是对autolayout约束创建动画

@IBAction func actionToggleMenu(sender: AnyObject) {
    isMenuOpen = !isMenuOpen
    menuHeightConstraint.constant = isMenuOpen ? 200.0 : 60.0
    titleLabel.text = isMenuOpen ? "Select Item" : "Packing List"
    UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 10.0, options: .CurveEaseIn, animations: { () -> Void in
            self.view.layoutIfNeeded()
            let angle = self.isMenuOpen ? CGFloat(M_PI_4) : 0.0
            self.buttonMenu.transform = CGAffineTransformMakeRotation(angle)
        }, completion: nil)
  }

创建动画的方式和之前一样,不过在动画闭包里面调用的是self.view.layoutIfNeeded(),所以使用自动布局的时候,如果是要做动画效果调用layoutIfNeeded()。在闭包里面还可以使用transform

Inspecting and animating constraints

前面是通过outlets来关联约束,然后对约束做动画。但是有时候没有使用IB,这样就没有约束了。

解决方法:你就要在运行时通过代码修改约束,做动画

UIView里面有个属性constraints,它会返回view的所有约束

for con in titleLabel.superview!.constraints {
  // 打印出所有的约束
  print(" -> \(con.description)\n")
}

通过判断找出需要修改的约束constant

for con in titleLabel.superview!.constraints {
   if con.firstItem as? NSObject == titleLabel && con.firstAttribute == .CenterX {
       con.constant = isMenuOpen ? -100 : 0.0
       continue
   }

Animating by replacing constraints

前面介绍了在运行时找出约束并修改constant,只是constantNSLayoutConstraint中唯一可变的属性,如果你想修改multiplier或者改变约束方式,你就要把当前约束移除并且添加新的你想要的约束。

打开Main.storyboard,双击某个约束,会发现约束的Identifier,你可以通过这个ID来找到相应的约束

if con.identifier == "TitleCenterY" {
   con.active = false
   continue
}

如果ID相同就是你要找的约束,设置active为false,view就会移除这个约束,如果也没有变量引用这个约束,那么约束就会在内存中被删除。

之后你要做的就是添加新的约束。

if con.identifier == "TitleCenterY" {
   con.active = false
   let newConstraint = NSLayoutConstraint(item: titleLabel, attribute: .CenterY, relatedBy: .Equal, toItem: titleLabel.superview!, attribute: .CenterY, multiplier: isMenuOpen ? 0.67 : 1.0, constant: 5.0)
   newConstraint.identifier = "TitleCenterY"
   newConstraint.active = true
   continue
}

新的约束identifier设置为TitleCenterY,下次就通过这个ID找到的约束就是你创建的新约束,active设置为true,告诉autolayout使用这个约束。

####注意 如果你是使用代码创建autolayout,必须调用UIView的addConstraint方法来添加你的约束到autolayout。但是在iOS8之后,添加约束的首选方法是设置它们的active属性或者调用**NSLayoutConstraint.activateConstraints(_:)**添加一个约束数组,一次性激活数组里的约束。

Clone this wiki locally