当应用程序重新进入前台时,iOS7 StatusBarHidden会破坏ScrollView

时间:2014-04-02 19:14:17

标签: ios cocoa-touch uiscrollview uinavigationbar ios7-statusbar

我的应用程序有一个Camera部分,它是一个模态呈现的UINavigationController,包含一个基于AVFoundation的CameraView,因为它是rootViewController。 用户可以按如下方式浏览他的照片库: 推送ViewController( - > Master),显示TableView中的所有AssetGroup。 当用户选择一个组时,将推送另一个ViewController,在CollectionView中显示该组中的所有资源。 为了屏幕空间和'风格',我决定在显示CameraSection时隐藏statusBar(使用setStatusBarHidden:withAnimation:) 这使NavigationController的NavigationBar向上滑动了20px(StatusBar高度)。

当我为资产浏览显示TableView / CollectionView时,我会考虑到这一点并为它们设置适当的conentInset等。

这一切都很好用,直到应用程序被发送到后台(主页 - 按钮),同时显示TableView或CollectionView。 (现在称它为“ScrollView”)

当应用程序重新进入前景时,“ScrollView”处于正确的状态非常短暂,然后它的帧向下偏移44px。 (44px =仅仅导航栏的实际大小 - 没有statusBar)。

以下是一些图片来说明问题:

在进入后台之前(主页按钮): Before entering the background

重新进入前台后: enter image description here

仔细观察,您可以看到navigationBar底部边缘的黑色发际线。在第一张图片中,一切都恰到好处。 但是,在第二个中,scrollView似乎有一个向下偏移44px的帧。

当collectionView的contentSize大于“Screen-Height”(开始可滚动)时,您还可以看到底部边缘太低(例如,最后一行不完全可见+ scrollIndicator-inset也是错误的)。

我已经尝试注册UIApplicationDidBecomeActiveNotificationUIApplicationDidChangeStatusBarFrameNotification等通知,并重新设置collectionView的contentInset和frame i回调。 Key-Value观察collectionView框架从未回调过,就像KVO是viewController的“topLayoutGuide”一样。

似乎框架在没有发出任何通知或事件的情况下悄然改变。 奇怪的是,当我重新输入前后NSLog的collectionView的frame和contentInset时,它们会显示完全相同的值!?

我根本不使用InterfaceBuilder,所以一切都在代码中完成(没有AutoLayout)。

我真的很感激有关这个问题的任何帮助。

现在,我担心我不得不满足于编写自定义navigationBar并隐藏navigationController来解决这个问题:/

  • 我注意到的另一个问题:当你隐藏statusBar时,scrollView的“scrollToTop”机制不再起作用。我想点按钮必须在状态栏上才能启动滚动,所以在隐藏statusBar时可以使用TapGestureRecog吗?

修改

FYI 我使用的每个ViewController都继承自将automagicallyAdjustScrollViewInset设置为NO。

的基类

1 个答案:

答案 0 :(得分:0)

修改

实际上,下面的解决方案也不对。

我发现它与navigationBar的translucent属性有关。 我在整个cameraSection中多次打开和关闭此属性。

保持此属性的稳定值后,一切正常。

老答案 - 不工作!!

好的,这非常非常难看,但我能够通过这样做来克服这个问题:

viewWillAppear:animated:中,注册以便在应用重新进入前景时收到通知。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(applicationDidBecomeActive:)
                                             name:UIApplicationDidBecomeActiveNotification
                                           object:nil];

回调如下:

- (void)applicationDidBecomeActive:(NSNotification *)notification
{
    UIEdgeInsets scrollIndicatorInset = self.collectionView.scrollIndicatorInsets;
    UIEdgeInsets contentInset = self.collectionView.contentInset;

    scrollIndicatorInset.top -= 44.0;
    scrollIndicatorInset.bottom += 44.0;

    contentInset.top -= 44.0;
    contentInset.bottom += 44.0;

    [self.collectionView setScrollIndicatorInsets:scrollIndicatorInset];
    [self.collectionView setContentInset:contentInset];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}

在调用一次回调时取消注册非常重要,因为否则在重新输入后,偏移量将会被破坏。

当然不是一个很好的解决方案,但解决方案是:/