在用xib中的约束做一些动画时,相信很多小伙伴都遇到不少坑,下面总结下最近自己遇到的一些坑,欢迎各位大神纠正以及指教:
layoutSubviews
该方法默认没人做任何事,需要自己重写,有很多地方系统会自动调用这个方法:
- 初始化时不会调用layoutSubviews,如果设置了非CGRectZero的frame就会调用
- 调用addSubView时,系统会自动调用layoutSubviews
- 当view的frame发生变化时,会调用layoutSubviews
- UIScrollView滚动的时候回调用layoutSubviews
setNeedsLayout
标记view需要重新布局,但是不会立刻刷新,系统会自动调用layoutSubviews,然后自行调用layoutIfNedded后,立刻刷新。
layoutIfNeeded
在有需要刷新的地方调用此方法
下面是几个例子:
- 例1:
@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *blueViewContant;
@end
- (IBAction)btnEvent:(id)sender {
[UIView animateWithDuration:3 animations:^{
self.blueViewContant.constant = 300;
}];
}
动画效果:
blueTest.gif
你会发现并没有什么卵用,而且制作gif的软件也有点辣鸡,压根没有这个动画过程,下面我试下用layoutIfNeeded方法
- 例2:
@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *blueViewContant;
@end
- (IBAction)btnEvent:(id)sender {
[UIView animateWithDuration:3 animations:^{
self.blueViewContant.constant = 300;
[self.view layoutIfNeeded];
}];
self.yellowViewContant.constant = 300;
}
blueTest.gif
这次效果就很明显了,就是说如果用xib中的Constraint来设置动画,一定要在开始动画的地方调用layoutIfNeeded方法,告诉系统这时候开始刷新
- 例3
@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *blueViewContant;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *yellowViewContant;
@end
- (IBAction)btnEvent:(id)sender {
[UIView animateWithDuration:3 animations:^{
self.blueViewContant.constant = 300;
[self.view layoutIfNeeded];
}];
self.yellowViewContant.constant = 300;
}
blueTest.gif
总结:如果想要用Constraint设置动画,一定要在调用layoutIfNeeded方面前设置Constraint的变化,如果不想view以动画的形式改变,那么久在调用layoutIfNeeded之后设置Constraint,或者不调用layoutIfNeeded.