如何动画使用AutoLayout向上滑动UIView?

Pan*_*ngu 8 objective-c uiview ios

这就是我想要实现的目标: 在此输入图像描述

我想执行一个向上滑动动画,用户可以向上滑动UIView2,UIView2将在屏幕中途停止.

我知道如何通过UIButton动作以模态方式呈现UIViewControler,如下所示:

[self presentViewController:newController animated:NO completion:nil];
Run Code Online (Sandbox Code Playgroud)

我也知道你需要这种类型的动画代码:

[UIView animateWithDuration:0.5f animations:^{
    [self.customView layoutIfNeeded];
} completion:^(BOOL finished) {

}];
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何使用UIViews实现这一点,特别是因为我将AutoLayout用于我的项目,并且我使用约束来轻松支持多种屏幕尺寸.

如何在不破坏AutoLayout和我设置的约束的情况下实现这一目标?

谢谢

San*_*man 17

我在这种情况下通常做的是以下内容.

为场景添加两个约束.一个UIView2与底部对齐的地方UIView1.第二个,它是对齐的中心UIView1(你需要在视图之间按住Ctrl键并拖动以适当地添加约束).这些约束最初会相互冲突,这很好.

IBOutlets 添加到视图控制器中,NSLayoutConstraints并将我们创建的两个约束分配给它们IBOutlet.

将初始条件的约束优先级设置为999(即,对齐到底部的约束优先级应为999).将目标约束的约束优先级设置为998(即,对齐中心的约束优先级为998).您现在将看到这些约束将不再发生冲突.这是因为一个约束的优先级会覆盖另一个约束.

你可能会看到现在的发展方向.因此,当您想要UIView2在约束之间制作动画时,请交换优先级和动画!

码:

@interface MyViewController ()
    @property (nonatomic, weak) IBOutlet NSLayoutConstraint* constraint0;
    @property (nonatomic, weak) IBOutlet NSLayoutConstraint* constraint1;
@end

- (void)someMethodWhereIWantToAnimate
{
    NSInteger temp = self.constraint0.priority;
    self.constraint0.priority = self.constraint1.priority;
    self.constraint1.priority = temp;

    [UIView animateWithDuration:0.3 animations:^{
        // Simplest is to use the main ViewController's view
        [self.view layoutIfNeeded];
    }];
}
Run Code Online (Sandbox Code Playgroud)

要启用平移并使用它来启动动画,请将Pan Gesture Recognizer添加到视图控制器.按Ctrl +拖动UIView2到Pan Gesture Recognizer并将其设置为gestureRecognizer.现在,当您拖动时UIView2,您将能够接收平移事件.

添加IBAction来处理平底锅:

- (IBAction)onPan:(id)sender
{
}
Run Code Online (Sandbox Code Playgroud)

Ctrl +从平移手势识别器拖动到视图控制器并设置onPan:为已发送的操作.

sender实际上是泛手势识别器本身.因此,我们将能够填写此方法来处理平移并UIView2在用户的手指下跟随,然后在他们放手时启动动画.

让我们开始填写代码:

- (IBAction)onPan:(id)sender
{
    UIPanGestureRecognizer* recognizer = (UIPanGestureRecognizer*)sender;
    CGPoint translation = [recognizer translationInView:self.view];
    NSLog(@"State: (%d) Translation in view: (%f, %f)", recognizer.state, translation.x, translation.y);
}
Run Code Online (Sandbox Code Playgroud)

如果您使用此代码运行,并将手指拖过UIView2,您将看到如下输出:

State: (1) Translation in view: (0.000000, -2.500000)
State: (2) Translation in view: (0.500000, -7.500000)
State: (2) Translation in view: (0.500000, -7.500000)
State: (2) Translation in view: (1.500000, -12.000000)
State: (2) Translation in view: (2.500000, -16.500000)
State: (2) Translation in view: (2.500000, -19.500000)
State: (2) Translation in view: (2.500000, -24.500000)
State: (2) Translation in view: (2.500000, -25.000000)
State: (2) Translation in view: (2.500000, -25.500000)
State: (2) Translation in view: (2.500000, -27.000000)
State: (2) Translation in view: (2.500000, -29.500000)
State: (2) Translation in view: (2.500000, -31.000000)
State: (2) Translation in view: (2.500000, -31.500000)
State: (3) Translation in view: (2.500000, -31.500000)
Run Code Online (Sandbox Code Playgroud)

请注意,值不断增加.我们想要增量.注意日志中的状态.状态(1)是拖动开始.状态(2)被拖动改变.拖拽状态(3).使用此信息,我们可以计算增量.

CGPoint属性添加到视图控制器并将UIView2添加为IBOutlet:

@property (nonatomic) CGPoint lastTranslation;
@property (nonatomic, weak) IBOutlet UIView* uiView2;
Run Code Online (Sandbox Code Playgroud)

最后,让我们填写pan方法的最终形式:

- (IBAction)onPan:(id)sender
{
    UIPanGestureRecognizer* recognizer = (UIPanGestureRecognizer*)sender;
    CGPoint delta;
    switch(recognizer.state) {
        case UIGestureRecognizerStateBegan:
            // On state begin: delta is the translation. Store it in our member for later user.
            self.lastTranslation = delta = [recognizer translationInView:self.view];
            break;
        case UIGestureRecognizerStateChanged:
            // On state changed: calculate the difference between the translation and our
            // previous translation.
            delta = CGPointApplyAffineTransform([recognizer translationInView:self.view], CGAffineTransformMakeTranslation(-self.lastTranslation.x, -self.lastTranslation.y));
            self.lastTranslation = [recognizer translationInView:self.view];
            break;
        case UIGestureRecognizerStateEnded:
            // On state ended: Let's just do the constraint animation.
            [self someMethodWhereIWantToAnimate];
            break;
        default:
            break;
    }
    delta.x = 0; // Forces only vertical drag on the UIView2.
    self.uiView2.center = CGPointApplyAffineTransform(self.uiView2.center, CGAffineTransformMakeTranslation(delta.x, delta.y)); // Move our uiView2 based on the delta.
    NSLog(@"State: (%d) Translation in view: (%f, %f)", recognizer.state, delta.x, delta.y);
}
Run Code Online (Sandbox Code Playgroud)

这样可以帮助您顺利完成任务.您可能希望根据平移手势的velocityInView:方法稍微调整一下UIView动画的约束 ,但我会将其作为练习留下.