iOS7 UIScrollView 在状态栏下方显示偏移内容

Posted

技术标签:

【中文标题】iOS7 UIScrollView 在状态栏下方显示偏移内容【英文标题】:iOS7 UIScrollView show offset content below status bar 【发布时间】:2013-11-06 15:59:55 【问题描述】:

我正在开发我的应用程序以使用 ios7。 我有一个 UINavigationController 我正在推动一个 UIViewController 里面有一个 ScrollView。在scrollView 里面我有一个tableView。 当我在 scrollView 内滚动 tableView 时,是否有可能实现该列表将出现在该状态栏的后面。如果我有一个 UINavigationController 和一个带有 tableView 的 UIViewController 也是一样的。

所以这是层次结构:

UINavigationController -> UIViewController -> UIScrollView -> UITableView

我希望当用户滚动表格时,顶部的单元格将在状态栏下可见。

如果没有UIScrollView,它会在 iOS7 中自动发生。

谢谢。

【问题讨论】:

很难理解您要达到的目标。考虑添加屏幕截图或指向示例。 【参考方案1】:

只需在 viewController init 方法中将automaticallyAdjustsScrollViewInsets 设置为NO

在Storyboard中,当UIViewController被选中时,可以直接在属性面板中切换属性。

如果你用的是xib,就这样设置吧:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self.automaticallyAdjustsScrollViewInsets = NO;

注意:从 iOS7 开始这是正确的,并且仍然在 iOS8 中。

【讨论】:

这是正确的解决方案,因为它不依赖于状态栏高度,它并不总是 20 像素(取决于正在通话的手机等)。 另外,您可以在情节提要中设置此行为。选择您的 viewController 并取消选中“调整滚动视图插图”选项。 谢谢你亲爱的朋友,我因为这件事浪费了半天时间。【参考方案2】:

以上方法都不适合我,直到我注意到我必须在 interfacebuilder 中将 Content Insets 从 Automatically 设置为 Never:

【讨论】:

我还必须取消选中“扩展边缘:在顶栏下” 谢谢!解决了一个大问题!【参考方案3】:

从 iOS 11 开始,您可以将此新属性与后备 (Swift 4) 一起使用:

if #available(iOS 11.0, *) 
    scrollView.contentInsetAdjustmentBehavior = .never
 else 
    self.automaticallyAdjustsScrollViewInsets = false

【讨论】:

正确答案现在在这里。【参考方案4】:

Skoua 的回答可能在某些情况下有效,但对 iOS11 及更高版本确实有一定的副作用。最值得注意的是,滚动视图将开始向其子级传播安全区域,如果您使用安全区域或布局边距,这可能会在滚动时弄乱您的布局。

Apple 在this WWDC session 中对此进行了很好的详细解释,并明确提到contentInsetAdjustmentBehavior = .never 可能有副作用,在大多数情况下不应该使用。


要获得一个不会打乱我们布局的滚动视图,而是在状态栏(或导航栏)下方显示其内容,您应该观察滚动视图的安全区域并相应地调整您的自定义内容插入:

private var scrollViewSafeAreaObserver: NSKeyValueObservation!

override func viewDidLoad() 

    ...

    if #available(iOS 11.0, *) 
        self.scrollViewSafeAreaObserver = self.scrollView.observe(\.safeAreaInsets)  [weak self] (_, _) in
            self?.scrollViewSafeAreaInsetsDidChange()
        
     else 
        self.automaticallyAdjustsScrollViewInsets = false
    


@available(iOS 11.0, *)
func scrollViewSafeAreaInsetsDidChange() 
    self.scrollView.contentInset.top = -self.scrollView.safeAreaInsets.top


deinit 
    self.scrollViewSafeAreaObserver?.invalidate()
    self.scrollViewSafeAreaObserver = nil

为什么会这样?因为我们离开了contentInsetAdjustmentBehavior = .automatic。当涉及到滚动和非滚动轴时,这将为我们提供正常的行为,但 UIScrollView 也会将任何安全区域“转换”为内容插入。由于我们不希望它用于我们的顶部边缘,我们只需将负顶部安全区域设置为我们的自定义插入,这将抵消滚动视图设置的任何插入。

【讨论】:

完美运行。谢谢!很好的解释。【参考方案5】:

这只是苹果公司的愚蠢。还要担心一种奇怪的行为。无论如何,我最终将顶部的滚动视图 content inset 设置为 -20(来自 IB)。

【讨论】:

我观察到 -20 到 [其他对象边缘] 约束通常可以修复这些奇怪的 UI 偏移行为。【参考方案6】:

我找到了解决方案!刚刚设置:

self.automaticallyAdjustsScrollViewInsets = false

在具有 UIScrollView 的视图控制器上。

【讨论】:

【参考方案7】:

您可能已经看过这个建议一千次了,但是,请查看 iOS 7 转换指南中的“状态栏”部分(无法在此处发布直接链接)。

直接恢复,在 ios7 上状态栏是视图的一部分。这意味着几乎所有你放在你的视图中的东西,都会在栏下,除非你说相反。我发现的解决该问题的方法是使状态栏不透明。

另一种方法是禁用该特定视图上的状态栏。 Like on this thread.

【讨论】:

【参考方案8】:

我遇到过类似的问题,我发现为了确保我的滚动视图内容不会出现在状态栏下方,我申请了setContentInset

因此,在您的情况下,如果您使用的是插图,我会建议使用为您的表格视图量身定制的 UIScrollViewDelegatescrollViewDidScroll。如果发生滚动,请忽略滚动视图插图。

【讨论】:

【参考方案9】:

statusBar不隐藏,scrollView不会跳转

【讨论】:

以上是关于iOS7 UIScrollView 在状态栏下方显示偏移内容的主要内容,如果未能解决你的问题,请参考以下文章

如何判断视图的视图控制器是不是在 iOS7 的状态栏下方扩展

iOS 状态栏和 UIView

在导航和状态栏下使用 pagingEnabled 扩展垂直 UIScrollView

如何让我的 iOS7 UITableViewController 不出现在顶部状态栏下?

如何在没有状态栏重叠的情况下在 iOS7 上呈现视图控制器

iOS 7 UI 变化:状态栏和导航控制器