我对自动布局很陌生,我对如何为视图制作动画感到困惑。
我读了很多,而且我知道你必须坚持约束,编辑它,并将layoutIfNeeded
包装在UIView
动画块中。
但是当谈到这样做时,我有点失落。如果有人能解释我this animation是如何完成的话,我会很高兴。
我认为它可能使用UIPanGestureRecognizer
将前导空格的constant
更改为容器约束,但它可能使用UIDynamics(对于右边的反弹效果?)。
答案 0 :(得分:16)
嗯,使用UIPanGestureRecognizer
+ [UIView animateWithDuration:animations:]
可以实现类似的行为。是的,您设置了前导空间约束并根据UIPanGestureRecognizer
状态进行更改。请记住,您只需要设置最终约束(定义滑块的最终位置)。为您计算中级动画位置。对于滑块,我们有默认左侧位置和激活中间位置。
对于视图轮换,我们可以使用transform
的{{1}}属性。
IB中的Autolayout约束:
设置动画选项(UIView
动画曲线)可以产生反弹效果。 UIViewAnimationOptionCurveEaseOut
代码(省略实例变量声明,因为它们的名称不言自明):
UIPanGestureRecognizer
- (IBAction)onPan:(UIPanGestureRecognizer*)sender
{
switch (sender.state) {
case UIGestureRecognizerStateBegan:
_startOffset = self.leadingSpace.constant;
_maxOffset = self.slider.superview.frame.size.width
- kHorizontalPadding
- self.slider.frame.size.width;
break;
case UIGestureRecognizerStateChanged: {
CGFloat offset = _startOffset + [sender translationInView:self.slider.superview].x;
offset = MIN(offset, _maxOffset);
self.leadingSpace.constant = offset;
break;
}
case UIGestureRecognizerStateEnded: {
CGFloat offset = _startOffset + [sender translationInView:sender.view.superview].x;
UIColor *bgColor = [UIColor lightGrayColor];
CGFloat rotation = 0;
if (offset < _maxOffset) {
offset = kHorizontalPadding;
}
else {
offset = (_maxOffset + kHorizontalPadding)/2;
bgColor = [UIColor redColor];
rotation = M_PI_2;
}
self.leadingSpace.constant = offset;
[UIView
animateWithDuration:.5
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self.slider layoutIfNeeded];
self.slider.backgroundColor = bgColor;
self.slider.transform = CGAffineTransformMakeRotation(rotation);
} completion:nil];
break;
}
default:
break;
}
}
(捕捉模拟器)的动画结果:
UIViewAnimationOptionCurveLinear
(捕捉模拟器)的动画结果:
<强> UIDynamics 强>
随着UIDynamics,事情变得更加复杂。好的起点是Ray Wenderlich UIKit Dynamics Tutorial。
对于弹跳滑块,我们可以添加以下行为:
UIViewAnimationOptionCurveEaseOut
拉动滑块开始位置。我们需要将UIGravityBehavior
属性更改为直接重力到左侧。angle
定义了允许移动的左右边缘。如果我们将父视图视为边界,UICollisionBehavior
属性将非常有用。此外,我们需要使用translatesReferenceBoundsIntoBoundary
(或bezier路径)添加额外的边界以在中间停止滑块。addBoundaryWithIdentifier:fromPoint:toPoint
分别更改UIDynamicItemBehavior
和elasticy
属性以配置退回和加速。resistance
与识别器的UIPushBehavior
一起指定用户释放滑块时的滑块速度velocityInView:
替代UISnapBehavior