73

我正在为 iOS 7 更新我的应用程序,但我发现了一个奇怪的问题。我正在展示一个 UIViewController 包装在一个 UINavigationController 中UIModalTransitionStyleFlipHorizontal

在 iOS 6 中它可以正常工作,但在 iOS 7 中导航栏在转换后会弹跳。这和状态栏有关系吗?我已将主导航栏的半透明设置为NO.

在 Info.plist 中,基于视图控制器的状态栏外观设置为 NO。

这是一个 GIF 在一个最小的演示应用程序中显示问题:

在此处输入图像描述

这是我的代码:

feedNavigationController = [[UINavigationController alloc] init];
feedNavigationController.navigationBar.translucent = NO;

SettingsViewController *settingsVC = [[SettingsViewController alloc] init];

feedNavigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[feedNavigationController setViewControllers:[NSArray arrayWithObjects:settingsVC, nil]];

[self presentViewController:feedNavigationController animated:YES completion:nil];
4

6 回答 6

54

这似乎是一个 UIKit 错误。以下解决方法似乎为我解决了这个问题。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar.layer removeAllAnimations];
}

(将它放在您要转换到的视图控制器中)。

于 2013-09-19T19:41:05.513 回答
16

为了解决这个问题,我使用了 iOS7 自定义过渡。

将此添加到您的 UIViewController :

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return (id<UIViewControllerAnimatedTransitioning>)self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    return (id<UIViewControllerAnimatedTransitioning>)self;
}

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

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    UIView *containerView = [transitionContext containerView];


    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    [containerView addSubview:fromVC.view];

    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    [containerView addSubview:toVC.view];

    UIViewAnimationOptions animationOption = ([toVC.presentedViewController isEqual:fromVC])?UIViewAnimationOptionTransitionFlipFromLeft:UIViewAnimationOptionTransitionFlipFromRight;


    [UIView transitionFromView:fromVC.view
                        toView:toVC.view
                      duration:[self transitionDuration:transitionContext]
                       options:animationOption
                    completion:^(BOOL finished) {
                        [transitionContext completeTransition:YES];
                    }];
}

要使用它,您只需检查您是否在 iOS7 上并设置 transitionDelegate :

YourVCWithTheCustomTransition* yourVC = [[YourVCWithTheCustomTransition alloc] init];

CGFloat deviceVersion = [UIDevice currentDevice].systemVersion.floatValue;
if(deviceVersion >= 7.0) [yourVC setTransitioningDelegate:yourVC];

[self presentModalViewController:yourVC animated:YES];
[yourVC release];

就我而言,我有一个自定义 UINavigationController ,其中定义了自定义转换:我不必每次都这样做。

于 2013-11-01T18:04:38.767 回答
9

This appears to be a UIKit bug. The following workaround seems to resolve the issue for me.

presentViewController (place this in the view controller you are transitioning to):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar.layer removeAllAnimations];
}

dismissViewControllerAnimated (place this in the view controller you dismiss to):

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [self.navigationController.navigationBar.layer removeAllAnimations];
}

if you don't use autolayout. you need add this to the view controller you dismiss to:

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self.view setNeedsLayout];
} 
于 2014-03-07T02:12:27.300 回答
3

我有同样的问题并且可以“解决它”(这不是问题的真正解决方案,但看起来不错:))。诀窍是使用pushViewController/popViewControllerUIView动画来呈现视图控制器以进行翻转。下面是展示视图控制器的示例代码:

UIViewController *viewController = [[UIViewController alloc] init];
[UIView transitionWithView:self.navigationController.view 
                  duration:0.5 
                   options:UIViewAnimationOptionTransitionFlipFromLeft 
                animations:^{
                   [self.navigationController pushViewController:viewController animated:NO];
                }
                completion:nil];

解雇它:

[UIView transitionWithView:self.navigationController.view 
                  duration:0.5 
                   options:UIViewAnimationOptionTransitionFlipFromRight 
                animations:^{
                   [self.navigationController popViewControllerAnimated:NO];
                }
                completion:nil];

如果您不希望navigationBar推送控制器上[self.navigationController setNavigationBarHidden:YES animated:NO]viewWillAppear. 我希望这种方法对您有所帮助。

于 2013-09-30T16:10:49.107 回答
1

对于呈现和呈现的视图控制器,我都有一个UITableViewControllerinside UINavigationController,两者都使用自动布局进行配置。我注意到其他答案并没有解决在关闭呈现视图控制器的 tableView 时垂直跳跃 20 pt 的问题。

这个解决方案解决了这个问题。

在呈现的视图控制器中(由 Ben Packard 提出):

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController.navigationBar.layer removeAllAnimations];
}

在呈现视图控制器中(部分由灰尘提出):

- (void)viewWillLayoutSubviews{
    if (self.navigationController.presentedViewController) {
        [self.navigationController.navigationBar.layer removeAllAnimations];
        [self.tableView.layer removeAllAnimations];
    }
    [super viewWillLayoutSubviews];
}
于 2014-07-09T13:51:08.397 回答
-2

我也一样。实际工作是将样式更改为 CoverVertical,看起来更流畅。

于 2013-09-22T04:37:32.700 回答