Autolayout,UIDynamics和动画

时间:2014-02-13 09:41:02

标签: ios animation autolayout uikit-dynamics

我对自动布局很陌生,我对如何为视图制作动画感到困惑。

我读了很多,而且我知道你必须坚持约束,编辑它,并将layoutIfNeeded包装在UIView动画块中。

但是当谈到这样做时,我有点失落。如果有人能解释我this animation是如何完成的话,我会很高兴。

我认为它可能使用UIPanGestureRecognizer将前导空格的constant更改为容器约束,但它可能使用UIDynamics(对于右边的反弹效果?)。

1 个答案:

答案 0 :(得分:16)

嗯,使用UIPanGestureRecognizer + [UIView animateWithDuration:animations:]可以实现类似的行为。是的,您设置了前导空间约束并根据UIPanGestureRecognizer状态进行更改。请记住,您只需要设置最终约束(定义滑块的最终位置)。为您计算中级动画位置。对于滑块,我们有默认左侧位置和激活中间位置。

对于视图轮换,我们可以使用transform的{​​{1}}属性。

IB中的Autolayout约束:

Autolayout constraints in IB

设置动画选项(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; } } (捕捉模拟器)的动画结果:

Animation result

UIViewAnimationOptionCurveLinear(捕捉模拟器)的动画结果:

Animation result

<强> UIDynamics

随着UIDynamics,事情变得更加复杂。好的起点是Ray Wenderlich UIKit Dynamics Tutorial

对于弹跳滑块,我们可以添加以下行为:

  • UIViewAnimationOptionCurveEaseOut拉动滑块开始位置。我们需要将UIGravityBehavior属性更改为直接重力到左侧。
  • angle定义了允许移动的左右边缘。如果我们将父视图视为边界,UICollisionBehavior属性将非常有用。此外,我们需要使用translatesReferenceBoundsIntoBoundary(或bezier路径)添加额外的边界以在中间停止滑块。
  • addBoundaryWithIdentifier:fromPoint:toPoint分别更改UIDynamicItemBehaviorelasticy属性以配置退回和加速。
  • 可能resistance与识别器的UIPushBehavior一起指定用户释放滑块时的滑块速度
  • 可能velocityInView:替代UISnapBehavior