自定义 Segue 中的 UIKit 动态 [英] UIKit Dynamics in a Custom Segue

查看:29
本文介绍了自定义 Segue 中的 UIKit 动态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让一个视图作为自定义转场转换下降,但是当在 UIStoryboardSegue 实现中调用 perform 方法时,它不会下降.我尝试将视图移动到源视图中以查看它是否有任何作用,但它没有.

I'm trying to make a view fall as a custom segue transition, but when the perform method is called in the UIStoryboardSegue implementation, it does not fall. I have tried moving the view to be dropped into the source's view to see if it does anything, but it doesn't.

-(void)perform {
    UIViewController *src  = (UIViewController *)self.sourceViewController;
    UIViewController *dest = (UIViewController *)self.destinationViewController;

    UIView *viewdrop = [dest.view snapshotViewAfterScreenUpdates:YES];
    viewdrop.frame = CGRectMake(0, -src.view.frame.size.height, dest.view.frame.size.width, dest.view.frame.size.height);
    [src.view addSubview:viewdrop];

    animator = [[UIDynamicAnimator alloc] initWithReferenceView:src.view];

    UIGravityBehavior* gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[viewdrop]];
    [animator addBehavior:gravityBehavior];
}

推荐答案

它没有下降的原因是重力行为需要时间,但是一旦 perform 方法完成,segue 本身就会被释放.因此,您需要一种方法至少在运动完成之前使转场保持活动状态.一种方法是在源视图控制器中为 segue 设置一个强属性,并在 prepareForSegue 中设置其值,

The reason it doesn't drop is because the gravity behavior takes time, but the segue itself is deallocated as soon as the perform method finishes. So, you need a way to keep the segue alive at least until the movement is complete. One way to do this is to make a strong property for the segue in the source view controller, and set its value in prepareForSegue,

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    self.dropSegue = segue;
}

我对你的 segue 做了一个修改版本,它也添加了碰撞行为,并将源视图控制器设置为碰撞行为的委托,所以我可以使用委托方法,collisionBehavior:endedContactForItem:withBoundaryIdentifier:,来设置dropSegue 属性为零(稍有延迟后),这会导致 segue 被释放,

I made a modified version of your segue that also adds a collision behavior, and sets the source view controller as the delegate of the collision behavior, so I can use the delegate method, collisionBehavior:endedContactForItem:withBoundaryIdentifier:, to set the dropSegue property to nil (after a slight delay) which causes the segue to be deallocated,

-(void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier {
    NSLog(@"collision ended with %@", identifier);
    [self performSelector:@selector(setDropSegue:) withObject:nil afterDelay:1];
}

这是我的重力下降segue版本,

Here is my version of the gravity drop segue,

@interface RDSegue ()
@property (strong, nonatomic) UIDynamicAnimator *animator;
@end

@implementation RDSegue

-(id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination {

    if (self = [super initWithIdentifier:identifier source:source destination:destination]) {
        UIViewController *src  = self.sourceViewController;
        UIViewController *dest = self.destinationViewController;
        self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:src.view];
        [src addChildViewController:dest];
        [dest didMoveToParentViewController:src];
        dest.view.frame = CGRectMake(0, -src.view.bounds.size.height, src.view.bounds.size.width, src.view.bounds.size.height);
        [src.view addSubview:dest.view];
    }
    return self;
}

-(void)perform {
    UIGravityBehavior* gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[[self.destinationViewController view]]];
    UICollisionBehavior *collide = [[UICollisionBehavior alloc] initWithItems:@[[self.destinationViewController view]]];
    CGPoint left = CGPointMake(self.animator.referenceView.bounds.origin.x, self.animator.referenceView.bounds.origin.y + self.animator.referenceView.bounds.size.height);
    CGPoint right = CGPointMake(self.animator.referenceView.bounds.origin.x + self.animator.referenceView.bounds.size.width, self.animator.referenceView.bounds.origin.y + self.animator.referenceView.bounds.size.height);
    [collide addBoundaryWithIdentifier:@"bottom" fromPoint:left toPoint:right];
    [collide setCollisionDelegate:self.sourceViewController];
    [self.animator addBehavior:gravityBehavior];
    [self.animator addBehavior:collide];
}

-(void)dealloc {
    NSLog(@"In dealloc");
}

这篇关于自定义 Segue 中的 UIKit 动态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆