是的,很明确的告诉各位看官,AutoLayout的确能做动画。AutoLayout是用来做各种约束,是用来适配不同屏幕的,那么当我们改变其中某些约束并讲这个改变的过程以缓慢的速度显示,那么是不是就实现了动画~
先来看一个酷炫的动画,这个动画由书籍iOS Animations by tutorials提供:
由书籍iOS Animations by tutorials提供
接下来我们将围绕这个动画的实现过程来进行叙述。
首先给我们最上方的这个类似Navigation的menu做动画,很明显我们在这里是改变了这个view的Height,既然如此,我们首先要做的就是获取这个menuView的约束条件,我们在代码中添加以下一行:
@IBOutlet var menuHeightConstraint: NSLayoutConstraint!
如何给约束条件做关联,首先找到我们的约束条件:
这个就是我们的menuView的高度的约束条件
双击这个约束条件,然后选择Connections Inspector,如下图操作:
1.png
然后选择menuHeightConstraint,这样我们就给约束条件做了一个关联。
现在我们在那个“+”按钮的方法里添加以下代码:
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: {
youtIfNeeded()
let angle = self.isMenuOpen ? CGFloat(M_PI_4) : 0.0
self.buttonMenu.transform = CGAffineTransformMakeRotation(angle)
}, completion: nil)
我们来看一下效果,我可以看到menuView很拽的下来了,还duang~duang~duang~的。这段代码在上一篇我们大多都讲过了,除了这个函数:
youtIfNeeded()
这个函数是什么意思呢,你可以这样理解,AutoLayout对于约束试一次计算,一次实现,但是当你加上这个函数以后,View还是一次实现了~~~额~~~但是,iOS没有机会去刷新视图,所有就会有动画的效果。~这一点好像和那个很废的包,java里的‘swing’有点类似~~~
对于 UIView.animateWithDuration这个函数若是有什么不懂的,请自行参考我的上一篇文章。
很多时候,我们不能或者不想给我们的约束做一个关联,那么这个时候我们如何获取我们的约束从而改变他呢?我们这里有一个函数.constraints()这个函数返回一个数组,这个数组中有这个控件的所有的约束。接下来我们给标题添加动画,我们上面看到,动画中标题duang~的一下跑到了左边。
for constraint in titleLabel.superview!.constraints() as! [NSLayoutConstraint] {
if constraint.secondItem as? NSObject == titleLabel && constraint.secondAttribute == .CenterX {
constraint.constant = isMenuOpen ? 100.0 : 0.0
continue
}
}
在这段代码中我们用前面提到的那个函数.constraints()获取了所有约束,然后用一个循环挨个检查,用if语句来寻找我们想要改变的约束。然后~~然后改变咯。
当然你也可以通过添加约束的方式来增加动画,如何添加约束,这里就不多说了,大体实现动画的方式和上面类似,你只需要添加youtIfNeeded()这个神奇的函数。
接下来的任务是添加那个横着的menu,就是那个有好多沙滩裤,还有一条比基尼的那个横幅。
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview == nil {
return
}
UIView.animateWithDuration(1.0, delay: 0.01, usingSpringWithDamping: 0.5, initialSpringVelocity: 10.0, options: .CurveEaseIn, animations: {
self.alpha = 1.0
self.center.x -= self.frame.size.width
}, completion: nil)
}
这个slider是HorizontalItemList类的,而这个HorizontalItemList类继承自UIScrollView,然后我们在他的
override func didMoveToSuperview()
函数中添加动画,那么当这个UI空间添加到view的时候就会执行这个动画,而至于这个动画实现则是非常简单,我们用很简单的函数,实现了很酷炫的动画。
最终任务:当点击列表的时候,在视图下方显示头像。
我们来理一下逻辑,我们首相要做的就是创建出个图像,然后给他约束,然后改变他的约束,以此来实现动画。
func showItem(index: Int) {
println("tapped item (index)")
//1
let imageView = UIImageView(image: UIImage(named: "summericons_100px_0(index).png"))
// imageView.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
yer.cornerRadius = 5.0
yer.masksToBounds = true
imageView.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(imageView)
let conX = NSLayoutConstraint(
item: imageView,
attribute: .CenterX,
relatedBy: .Equal,
toItem: view,
attribute: .CenterX,
multiplier: 1.0,
constant: 0.0)
conX.active = true
let conY = NSLayoutConstraint(
item: imageView,
attribute: .Bottom,
relatedBy: .Equal,
toItem: view,
attribute: .Bottom,
multiplier: 1.0,
constant: imageView.frame.size.height)
conY.active = true
let conWidth = NSLayoutConstraint(
item: imageView,
attribute: .Width,
relatedBy: .Equal,
toItem: view,
attribute: .Width,
multiplier: 0.33,
constant: -50.0)
conWidth.active = true
let conHeight = NSLayoutConstraint(
item: imageView,
attribute: .Height,
relatedBy: .Equal,
toItem: imageView,
attribute: .Width,
multiplier: 1.0,
constant: 0.0)
conHeight.active = true
youtIfNeeded()
//2
UIView.animateWithDuration(0.8, delay: 0.0,
usingSpringWithDamping: 0.4, initialSpringVelocity: 0.0,
options: nil, animations: {
conY.constant = -imageView.frame.size.height/2
conWidth.constant = 0.0
youtIfNeeded()
}, completion: nil)
UIView.animateWithDuration(0.8, delay: 1.0, options: nil, animations: {
conY.constant = imageView.frame.size.height
conWidth.constant = -50.0
youtIfNeeded()
}, completion: {_ in
imageView.removeFromSuperview()
})
}
}
来解释一下这段代码:
//1 创建了四个约束,包括conY、conX、conHeight、conHeight。
//2 通过修改约束来实现动画,前面已经讲过了。
那么现在唯一令大家疑惑的可能只有穿件约束的那些个属性了,我们拿第一个来举例:
let conX = NSLayoutConstraint(
item: imageView,
attribute: .CenterX,
relatedBy: .Equal,
toItem: view,
attribute: .CenterX,
multiplier: 1.0,
constant: 0.0)
conX.active = true
item:约束的第一个对象。
attribute:第一个对象的属性。
relatedBy: 约束的一些其他作用,在这里只用.Equal。
toItem: 约束的第二个对象。
attribute: 第二个对象的属性。
multiplier: 乘数。
constant: 约束的值。
好的我们基本实现了所有的酷酷的动画。
终结一下就是改变约束条件,配合上函数youtIfNeeded()。