使用自定义segue转到ViewController会导致viewWillAppear被调用两次

时间:2015-10-21 07:15:05

标签: ios objective-c uiviewcontroller

我写了一个自定义的segue,因为我想添加自己的动画。除了目标视图CiewController中的viewDidLoad方法被调用两次之外,一切正常。这是我的segue的执行方法:

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

    [sourceViewController.view addSubview:destinationViewController.view];

    CGPoint originalCenter = destinationViewController.view.center;
    destinationViewController.view.center = CGPointMake(self.originatingPoint.x * 3, self.originatingPoint.y);

    [UIView animateWithDuration:0.25
        delay:0.0
        options:UIViewAnimationOptionCurveEaseInOut
        animations:^{
            destinationViewController.view.center = originalCenter;
        }
        completion:^(BOOL finished) {
            [sourceViewController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC
        }];
}

有谁知道可能导致这种情况的原因?

[-----编辑-----]

segue在故事板中作为自定义segue存在,我自己编写了一个segue类。我班上唯一不同的是我上面提到的执行方法。 segue是通过按钮调用的,而prepareForSegue方法只调用一次。

[-----编辑2 -----]

我检查了targetVC的viewDidLoad方法,每个segue只调用一次。尽管如此,使用viewWillAppear对我来说会更方便,所以你可能知道我可以用这种动画做不同的方式吗?

1 个答案:

答案 0 :(得分:3)

我建议您使用UIViewControllerTransitioningDelegateUIViewControllerAnimatedTransitioning这些更适合用于iOS 7.0以来的转换的约定。从iOS 8.0开始,您还可以获得UIPresentationController支持,从而可以构建更丰富的过渡。

示例:

@interface ModalTransitionAnimator : NSObject<UIViewControllerAnimatedTransitioning>

@property (nonatomic) CGPoint originatingPoint;

@end

@implementation ModalTransitionAnimator

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.25;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    NSTimeInterval duration = [self transitionDuration:transitionContext];
    UIView* sourceView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView* destinationView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView* container = transitionContext.containerView;

    [container addSubview:destinationView];

    CGPoint originalCenter = destinationView.center;

    destinationView.center = CGPointMake(self.originatingPoint.x * 3, self.originatingPoint.y);

    [UIView animateWithDuration:duration animations:^{
            destinationView.center = originalCenter;
        }
        completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
}

@end

然后在prepareForSegue中,您只需指定转换委托并实施UIViewControllerTransitioningDelegate即可返回适当的动画制作人员进行演示或解雇。

@interface ViewController : UIViewController<UIViewControllerTransitioningDelegate>
@end

@implementation ViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    UIViewController* controller = (UIViewController*)segue.destinationViewController;

    controller.transitioningDelegate = self;
    controller.modalPresentationStyle = UIModalPresentationCustom;
    controller.modalPresentationCapturesStatusBarAppearance = YES;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    ModalTransitionAnimator *animator = [[ModalTransitionAnimator alloc] init];
    animator.originatingPoint = /* ... */;

    return animator;
}

@end

由于这是模态转换,因此在向控件提供控制器时必须使用presentViewController:animated:。因此,使用普通&#34;显示&#34;在故事板中细分,它们会自动运行引擎盖下的所有动画,不需要在这里重新发明细分。

我有一个如何在Github上构建自定义转换的示例:

https://github.com/pronebird/CustomModalTransition/tree/ios8