如何使用AutoLayoutanimation滑动UIView?
这是我想要实现的:
我想执行一个向上滑动的animation,用户可以向上滑动一个UIView2,UIView2将在屏幕上中途停止。
我知道如何通过一个UIButton动作来模式地呈现一个UIViewControler,如下所示:
[self presentViewController:newController animated:NO completion:nil];
我也知道你需要这种types的animation代码:
[UIView animateWithDuration:0.5f animations:^{ [self.customView layoutIfNeeded]; } completion:^(BOOL finished) { }];
但是,我不知道如何实现这与UIViews,尤其是因为我使用AutoLayout为我的项目,并使用约束来轻松支持多种屏幕尺寸。
我怎样才能实现这个不破坏AutoLayout和我设置的约束?
谢谢
我通常在这种情况下做的是以下几点。
在场景中添加两个约束。 UIView2
与UIView2
的底部alignment。 第二,它alignmentUIView1
的中心(你会想按CTRL +拖动视图之间添加约束)。 这些约束最初会相互冲突,没关系。
将IBOutlet
添加到NSLayoutConstraints
视图控制器中, NSLayoutConstraints
我们创build的两个约束分配给这些IBOutlet
。
将您的初始条件的约束优先级设置为999(即alignment至底部的约束优先级应为999)。 将目标约束上的约束优先级设置为998(即alignment中心的约束优先级为998)。 您现在将会看到这些限制不会再发生冲突。 这是因为一个约束的优先级会覆盖另一个约束。
你现在可以看到这个方向。 所以当你想在约束之间animationUIView2
,交换优先级和animation!
码:
@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]; }]; }
要启用平移并使用它开始animation,请将Pan Gesture识别器添加到视图控制器。 按住Ctrl UIView2
并从UIView2
拖动到Pan Gesture识别器,并将其设置为一个gestureRecognizer
。 现在,当你在UIView2
上UIView2
,你将能够接收到泛的事件。
添加一个IBAction来处理泛:
- (IBAction)onPan:(id)sender { }
按住Ctrl键并从平移手势识别器拖动到视图控制器,并将onPan:
设置为发送的操作。
sender
实际上是泛手势识别器本身。 所以我们可以填写这个方法来处理一个泛,并且在用户的手指下面有UIView2
,然后在放开的时候启动animation。
我们开始填写代码:
- (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); }
如果你运行这个代码,并拖动你的手指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)
请注意,这些值不断增加。 我们需要增量。 注意日志中的状态。 状态(1)是拖动启动。 状态(2)被拖拽改变。 状态(3)拖动结束。 使用这个信息,我们可以计算出三angular洲。
将CGPoint
属性添加到您的视图控制器,并添加UIView2作为IBOutlet:
@property (nonatomic) CGPoint lastTranslation; @property (nonatomic, weak) IBOutlet UIView* uiView2;
最后,让我们填写我们的pan方法的最终forms:
- (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); }
这应该让你顺利。 你可能想看看基于平移手势的velocityInView:
方法调整约束上的UIViewanimation,但是我将作为练习离开。