我读了很多,我知道你必须坚持约束,编辑它,并将layoutIfNeeded包装在UIView动画块中.
但是当谈到这件事时,我有点迷失了.如果有人可以解释我如何完成this animation,我会很乐意.
我认为它可能使用UIPanGestureRecognizer来将前导空间的常量更改为容器约束,但它可能使用UIDynamics(在右侧的反弹效果).
解决方法@H_301_10@
那么,UIPanGestureRecognizer可以实现类似的行为[UIView animateWithDuration:animations:].是的,你设置了领先的空间约束,并根据UIPanGestureRecognizer状态进行更改.记住,您只需要设置最终约束(定义滑块的最终位置).中级动画职位是为您计算的.对于滑块,我们有默认左位置和激活的中间位置.
对于视图旋转,我们可以使用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
对于视图旋转,我们可以使用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