我对自动布局很陌生,我对如何为视图设置动画感到困惑。
我读了很多,我知道你必须遵守约束,编辑它,并将它包装layoutIfNeeded
在一个UIView
动画块中。
但说到做到这一点,我有点迷失了。例如,如果有人可以向我解释这个动画是如何完成的,我会很高兴。
我认为它可能使用 a将前导空间UIPanGestureRecognizer
更改为容器约束,但它可能使用 UIDynamics(用于右侧的反弹效果?)。constant
我对自动布局很陌生,我对如何为视图设置动画感到困惑。
我读了很多,我知道你必须遵守约束,编辑它,并将它包装layoutIfNeeded
在一个UIView
动画块中。
但说到做到这一点,我有点迷失了。例如,如果有人可以向我解释这个动画是如何完成的,我会很高兴。
我认为它可能使用 a将前导空间UIPanGestureRecognizer
更改为容器约束,但它可能使用 UIDynamics(用于右侧的反弹效果?)。constant
UIPanGestureRecognizer
好吧,使用+可以实现类似的行为[UIView animateWithDuration:animations:]
。是的,您设置了前导空间约束并根据UIPanGestureRecognizer
状态进行更改。请记住,您只需要设置最终约束(定义滑块的最终位置)。为您计算中间动画位置。对于滑块,我们有默认的左侧位置和激活的中间位置。
对于视图旋转,我们可以使用transform
.UIView
IB中的自动布局约束:
设置动画选项(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
(捕获模拟器):
动画结果UIViewAnimationOptionCurveEaseOut
(捕获模拟器):
UIDynamics
使用 UIDynamics,事情变得更加复杂。好的起点是Ray Wenderlich UIKit Dynamics Tutorial。
对于弹跳滑块,我们可以添加以下行为:
UIGravityBehavior
它将滑块拉到起始位置。我们需要更改angle
属性以将重力指向左侧。UICollisionBehavior
它定义了允许运动的左右边缘。translatesReferenceBoundsIntoBoundary
如果我们将父视图视为边界,属性将很有用。此外,我们需要添加额外的边界以使用addBoundaryWithIdentifier:fromPoint:toPoint
(或贝塞尔路径)在中间停止滑块。UIDynamicItemBehavior
更改elasticy
和可能resistance
的属性以分别配置反弹和加速。UIPushBehavior
与识别velocityInView:
器一起指定滑块速度UISnapBehavior
作为替代品UIGravityBehavior