【问题标题】:iOS7 UIModalTransitionStyleFlipHorizontal bounces after transitioniOS7 UIModalTransitionStyleFlipHorizo​​ntal 过渡后反弹
【发布时间】:2013-09-17 20:35:55
【问题描述】:

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

在 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];

【问题讨论】:

  • 很遗憾找不到视频。
  • 我也有同样的问题。
  • 完全相同的问题,GM 版本有一些 Biig 问题,collectionView reloadData 也是一个!
  • 不适合我! iOS 8 仍然存在这个问题。视图中的 self.navigationController?.navigationBar.layer.removeAllAnimations() 将为我修复它。
  • 在我的项目中也是如此,在 iOS9 上,我使用 UIView transitionFromView:toView:duration:options:completion: 在两个视图控制器之间切换并面临这个错误。以下答案解决了导航栏高度的问题,但不是它的色调,有人遇到过这个问题吗?

标签: ios cocoa-touch uiviewcontroller uinavigationcontroller uimodaltransitionstyle


【解决方案1】:

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

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

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

(将其放置在要转换的视图控制器中)。

【讨论】:

  • 这对我有用。确保在导航控制器的根视图控制器中执行此操作,而不是导航控制器本身。
  • 有趣 - 解雇时究竟会发生什么?
  • 解雇时也会发生同样的事情。所以这只能部分解决问题。将此添加到开始转换的视图控制器(来自视图控制器)并不能解决关闭和转换回来时的问题。
  • 我明白了 - 我从没有导航栏的控制器翻转,所以从来没有遇到过这种情况。从技术上讲,它解决了上述问题;)
  • 这在第一次调用动画时对我有用,但在任何后续调用中都不起作用。为什么会这样,因为每次视图出现时都会调用它???令人抓狂。
【解决方案2】:

对我来说也一样。实际可行的是将样式更改为 CoverVertical,看起来更流畅。

【讨论】:

    【解决方案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,只需在viewWillAppear 中调用[self.navigationController setNavigationBarHidden:YES animated:NO]。我希望这种方法对您有所帮助。

    【讨论】:

    • 这实际上解决了过渡双方的问题,这不是上面的答案所做的。如果您在模态控制器上有一个导航栏,您可能需要将左栏按钮项设置为 nil 以获得您在 iOS6 上的确切效果(无后退按钮)但仅此而已。
    • 顺便说一下,由于某种原因,此方法会导致导航栏出现视觉故障(尽管不如不使用它严重)。主要是标题和后退按钮文本直到过渡后才会显示,并且在过渡期间是空白的。
    • 这应该是公认的答案,它是双向转换的完美解决方法。只需检查在推送时隐藏底部栏并根据需要在视图中隐藏/取消隐藏导航栏将出现推送和推送控制器的方法。
    【解决方案4】:

    为了解决这个问题,我使用了 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,其中定义了自定义转换:我不必每次都这样做。

    【讨论】:

    • 添加“else yourVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizo​​ntal;”后效果很好在 deviceVersion 的测试中,所以它在 iOS6 中继续工作。
    • 这应该是公认的答案。完美运行。我唯一的建议是将这段代码放在一个单独的类中,然后您可以在任何视图控制器中使用它。
    • Don't check for the system version 但检查方法是否可用:if ([yourVC respondsToSelector:@selector(setTransitioningDelegate:)] { [yourVC setTransitioningDelegate:yourVC]; }
    • 很好用,我唯一要做的就是将代理设置为“viewwillappear”,因为我的一些视图通过情节提要编辑器定义了转场。
    • 有趣的是,在 iOS 8 下,从这个转换返回会导致永久的白屏。当然,在 iOS 8 下你不需要做任何这些,因为修复了这个必要的错误。
    【解决方案5】:

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

    presentViewController(将其放置在您要转换到的视图控制器中):

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

    dismissViewControllerAnimated(将其放置在您关闭的视图控制器中):

    - (void)viewWillLayoutSubviews{
        [super viewWillLayoutSubviews];
    
        [self.navigationController.navigationBar.layer removeAllAnimations];
    }
    

    如果你不使用autolayout。您需要将此添加到您 dismiss 的视图控制器中:

    - (void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
    
        [self.view setNeedsLayout];
    } 
    

    【讨论】:

    • 对不起,我上次贴错了代码。这段代码对我有用。
    • 这对我来说绝对有效。故事板截图:cl.ly/image/060t10100b2W
    • 我可以确认这对我也有效。 iOS 7.1.1
    【解决方案6】:

    对于呈现和呈现的视图控制器,我在UINavigationController 中都有一个UITableViewController,两者都使用自动布局进行配置。我注意到其他答案并没有解决在关闭当前视图控制器的 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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 2015-02-28
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      相关资源
      最近更新 更多