OGeek|极客世界-中国程序员成长平台

标题: ios - 使用自定义 segue 转到 ViewController 会导致 viewWillAppear 被调用两次 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 09:29
标题: ios - 使用自定义 segue 转到 ViewController 会导致 viewWillAppear 被调用两次

我写了一个自定义的segue,因为我想给它添加我自己的动画。一切正常,除了目标 View CiewController 中的 viewDidLoad 方法被调用了两次。这是我的 segue 的 perform 方法:

- (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 类。在我的类(class)中唯一不同的是我上面提到的 perform 方法。 segue通过按钮调用,prepareForSegue方法只调用一次。

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

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



Best Answer-推荐答案


我建议您使用 UIViewControllerTransitioningDelegateUIViewControllerAnimatedTransitioning 这是自 iOS 7.0 起更适合用于转换的约定。从 iOS 8.0 开始,您还获得了 UIPresentationController 支持,允许您构建更丰富的过渡。

例子:

@interface ModalTransitionAnimator : NSObject<UIViewControllerAnimatedTransitioning>

@property (nonatomic) CGPoint originatingPoint;

@end

@implementation ModalTransitionAnimator

- (NSTimeInterval)transitionDurationid<UIViewControllerContextTransitioning>)transitionContext {
    return 0.25;
}

- (void)animateTransitionid<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 中,您只需分配过渡委托(delegate)并实现 UIViewControllerTransitioningDelegate 以返回适当的动画器以进行演示或解除。

@interface ViewController : UIViewController<UIViewControllerTransitioningDelegate>
@end

@implementation ViewController

- (void)prepareForSegueUIStoryboardSegue *)segue senderid)sender {
    UIViewController* controller = (UIViewController*)segue.destinationViewController;

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

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedControllerUIViewController *)presented presentingControllerUIViewController *)presenting sourceControllerUIViewController *)source {
    ModalTransitionAnimator *animator = [[ModalTransitionAnimator alloc] init];
    animator.originatingPoint = /* ... */;

    return animator;
}

@end

由于这是一个模态转换,因此您必须在使用它呈现 Controller 时使用 presentViewController:animated:。因此,在 Storyboard 中使用普通的“显示”转场,它们会自动运行所有动画,无需在这里重新发明转场。

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

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

关于ios - 使用自定义 segue 转到 ViewController 会导致 viewWillAppear 被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33253112/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4