如何使用 iOS 6 SDK 解决 hidesBottomBarWhenPushed 的奇怪行为?

Posted

技术标签:

【中文标题】如何使用 iOS 6 SDK 解决 hidesBottomBarWhenPushed 的奇怪行为?【英文标题】:How can I work around hidesBottomBarWhenPushed acting weird with the iOS 6 SDK? 【发布时间】:2013-09-15 15:09:53 【问题描述】:

我遇到了this OpenRadar issue 中描述的相同问题。如那里所述:

总结:UIViewController 的 hidesBottomBarWhenPushed 属性 对于使用 ios 6 SDK(不是 beta SDK)构建的应用程序无法正常工作 对于 iOS 7)。隐藏底栏时动画很奇怪(例如 标签栏)。

复制步骤:

    在 Xcode 4 中使用 TabBar 模板创建一个新项目。将 UINavigationController 添加到 FirstViewController。在上面添加一个按钮 FirstViewController 并设置它的动作来推送一个新的视图控制器。 (请看附件示例代码)

    在 iOS 7 beta 5 设备上运行演示。

    按下按钮,从 UINavigationController 返回,注意动画视图转换。

预期结果:动画效果与 iOS 6 上的完全相同 设备。

实际结果:动画看起来很奇怪。 FirstViewController 是 从底部滑下来。

示例代码:http://cl.ly/QgZZ

在使用 iOS 6 SDK 构建时,有什么方法可以修复或解决这个问题?

【问题讨论】:

在 iOS 7 中面临同样的问题 :( 【参考方案1】:

这个问题肯定存在。我做了一些调查,发现是什么原因造成的。当使用UINavigationController 推送视图控制器时,视图控制器的视图包含在UIViewControllerWrapperView 中,这是由UINavigationController 管理的私有Apple 视图。当过渡动画即将发生并且 hidesBottomBarWhenPushed 设置为 YES 时,此 UIViewControllerWrapperView 的动画在 Y 轴上使用错误的 position,因此解决方案只是覆盖此行为并为动画片。代码如下:

//Declare a property
@property (nonatomic, assign) BOOL shouldFixAnimation;

...

- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];

#ifndef __IPHONE_7_0 //If this constant is not defined then we probably build against lower SDK and we should do the fix
    if (self.hidesBottomBarWhenPushed && [[[UIDevice currentDevice] systemVersion] floatValue] >= 7 && animated && self.navigationController) 
        self.shouldFixAnimation = YES;
    
#endif



-(void)viewWillLayoutSubviews 
    [super viewWillLayoutSubviews];

#ifndef __IPHONE_7_0
    if(self.shouldFixAnimation) 
        self.shouldFixAnimation = NO;
        CABasicAnimation *basic = (CABasicAnimation *)[self.view.superview.layer animationForKey:@"position"]; //The superview is this UIViewControllerWrapperView

        //Just in case for future changes from Apple
        if(!basic || ![basic isKindOfClass:[CABasicAnimation class]]) 
            return;

        if(![basic.fromValue isKindOfClass:[NSValue class]])
            return;

        CABasicAnimation *animation = [basic mutableCopy];

        CGPoint point = [basic.fromValue CGPointValue];

        point.y = self.view.superview.layer.position.y;

        animation.fromValue = [NSValue valueWithCGPoint:point];

        [self.view.superview.layer removeAnimationForKey:@"position"];
        [self.view.superview.layer addAnimation:animation forKey:@"position"];
    
#endif


【讨论】:

它在 Push 上就像一个魅力!但现在面临弹回问题:( 您也可以为启动推送的控制器执行此操作。只需在 if 中删除 hidesBottomBarWhenPushed 即可。根据您的需要进行调整。 你可以把两个都放,一个是推的,一个是推的。对于推送的人,请确保删除对self.hidesBottomBarWhenPushed 的检查(如果没有)。【参考方案2】:

在我的情况下,我在每个选项卡中都有 TabBarViewControllerUINavigationController 并面临类似的问题。 我用过,

nextScreen.hidesBottomBarWhenPushed = true
pushViewToCentralNavigationController(nextScreen)

当 nextScreen 是 UITableViewController 子类并应用自动布局时,它可以正常工作。 但是,当nextScreenUIViewController 时,它不能正常工作。我发现它取决于nextScreen 自动布局约束。

所以我刚刚用这段代码更新了我的 currentScreen -

override func viewWillDisappear(animated: Bool) 

        super.viewWillDisappear(animated)

        self.tabBarController?.tabBar.hidden = true

    

这样你可以达到预期的结果,但它不是实现它的好方法。

希望对你有帮助。

【讨论】:

以上是关于如何使用 iOS 6 SDK 解决 hidesBottomBarWhenPushed 的奇怪行为?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 FB SDK 3.1 和 iOS<6 预览 facebook 状态更新?

在 + UIDocumentInteractionController 中打开:如何在 SDK iOS 6 中过滤选项(不推荐使用 canPerformActions)

在 XCode 上使用 iOS SDK 6 开发时如何排除 UIActivityTypeAirDrop?

使用 iOS 7 SDK 的随机 iOS 6 崩溃

Unity sdk 版本等于0,无法打包如何解决

如何使用 Titanium 重新安装所有用于 iOS 开发的旧 SDK(软件)?