我读了很多,我知道你必须坚持约束,编辑它,并将layoutIfNeeded包装在UIView动画块中.
但是当谈到这件事时,我有点迷失了.如果有人可以解释我如何完成this animation,我会很乐意.
我认为它可能使用UIPanGestureRecognizer来将前导空间的常量更改为容器约束,但它可能使用UIDynamics(在右侧的反弹效果).
解决方法
对于视图旋转,我们可以使用UIView的transform属性.
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将一个滑块拉到起始位置.我们需要改变角度属性以将重力向左引导.> UICollisionBehavior定义允许动作的左边缘和右边缘.如果我们将父视图视为边界,则translateReferenceBoundsIntoBoundary属性将非常有用.另外我们还需要添加额外的边界,使用addBoundaryWithIdentifier:fromPoint:toPoint(或bezier path)在中间停止滑块.> UIDynamicItemBehavior来改变弹性和可能的阻力属性,分别配置反弹和加速.>可能的UIPushBehavior与识别器的velocityInView结合使用:在用户释放滑块时指定滑块速度>可能的UISnapBehavior作为替代UIGravityBehavior