UIViewController 自定义转换和状态恢复

Posted

技术标签:

【中文标题】UIViewController 自定义转换和状态恢复【英文标题】:UIViewController custom transitions and state restoration 【发布时间】:2014-03-12 18:43:28 【问题描述】:

我有一个使用自定义转换的视图控制器,它运行良好。它利用了这样一个事实,即在使用 UIModalPresentationCustom 时,呈现的视图控制器不会被移除,而是将新的视图控制器以透明的方式放置在它上面。

但是,当将此与状态恢复结合使用时,呈现的视图控制器将被移除。似乎因为视图控制器没有动画呈现,自定义转换代码永远不会被调用。有没有办法激活自定义转换,即使视图控制器没有动画?

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                  presentingController:(UIViewController *)presenting
                                                                      sourceController:(UIViewController *)source

    // never called if we aren't animating
    return self;


- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed

    return self;


- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext

    return 0.25;


- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext

    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (toViewController == self) 
        [transitionContext.containerView addSubview:fromViewController.view];
        [transitionContext.containerView addSubview:toViewController.view];

        self.maskView.alpha = 0.0f;
        self.menuView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, 286.0f);

        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^
            fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;

            [self.menuView updateFrame:^(CGRect *frame) 
                frame->origin.y = self.view.bounds.size.height - frame->size.height;
            ];

            self.maskView.alpha = 0.75f;
         completion:^(BOOL finished) 
            self.maskView.userInteractionEnabled = YES;
            [transitionContext completeTransition:YES];
        ];
     else 
        [transitionContext.containerView addSubview:toViewController.view];
        [transitionContext.containerView addSubview:fromViewController.view];

        self.maskView.userInteractionEnabled = NO;

        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^
            toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;

            [self.menuView updateFrame:^(CGRect *frame) 
                frame->origin.y = self.view.bounds.size.height;
            ];

            self.maskView.alpha = 0.0f;
         completion:^(BOOL b)
            [transitionContext completeTransition:YES];

            [self.menuView updateFrame:^(CGRect *frame) 
                frame->origin.y = self.view.bounds.size.height - frame->size.height;
            ];
        ];
    

【问题讨论】:

【参考方案1】:

我看不到如何在状态恢复时从层次结构中删除您的presentingVC,但将以下内容放入您的应用委托中会有所帮助:

- (UIViewController*)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder 
    NSLog(@"Application restore state = %@", [identifierComponents componentsJoinedByString:@"."]);

    return nil;

如果您不实现自定义状态恢复类并依靠 Storyboard 为您执行此操作,您可以通过这种方式遵循状态恢复逻辑。这可能会让人深思。

【讨论】:

以上是关于UIViewController 自定义转换和状态恢复的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义转换旋转模态 UIViewController

从UINavigationController中解除具有自定义转换的UIViewController时出现黑屏

如何在将 UIViewController 呈现给自定义时更改默认转换

从 UINavigationController 中通过自定义转换关闭 UIViewController 时出现黑屏

在 Swift 中使用 animateWithDuration 自定义 UIViewController 转换

如何使用自定义 UIViewController 转换来实现这一点?