0

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

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

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

当应用程序重新进入前台时,“ScrollView”在很短的时间内处于正确状态,然后它的框架向下偏移 44px。(44px = 导航栏的实际大小 - 没有状态栏)。

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

进入后台之前(主页按钮): 进入后台前

重新进入前台后: 在此处输入图像描述

仔细看,可以看到navigationBar底部边缘的黑色细线。在第一张图片中,一切都对齐得恰到好处。然而,在第二个中,scrollView 似乎有一个向下偏移 44px 的框架。

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

我已经尝试注册类似UIApplicationDidBecomeActiveNotificationor的通知UIApplicationDidChangeStatusBarFrameNotification,并在回调中重新设置 collectionView 的 contentInset 和框架。观察collectionView框架的Key-Value从不回调,就像KVO viewController的“topLayoutGuide”一样。

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

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

我非常感谢有关此问题的任何帮助。

现在,恐怕我不得不满足于编写自定义导航栏并隐藏导航控制器来解决这个问题:/

  • 我注意到的另一个问题:当您隐藏状态栏时,scrollView 的“scrollToTop”机制不再起作用。我想点击必须在状态栏上才能开始滚动,所以在隐藏状态栏的同时让它工作,一个 TapGestureRecog 是必要的吗?

编辑

仅供参考,我使用的每个 ViewController 都继承自设置automagicallyAdjustScrollViewInset为 NO 的基类。

4

1 回答 1

0

编辑

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

我发现它与导航栏的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];
}

当回调被调用一次时取消注册很重要,因为否则偏移量会在额外的重新输入后被破坏。

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

于 2014-04-02T19:41:41.243 回答