iOS 11 超大导航栏标题速度意外

iOS 11 large navigation bar title unexpected velocity

我正在尝试在我的新应用程序上实现 iOS11 本机大导航栏标题。通过在 viewDidLoad() 中调用以下函数:

navigationController?.navigationBar.prefersLargeTitles = true navigationController?.navigationItem.largeTitleDisplayMode = .always

我确实得到了我想要的。

但是,当我开始向上滚动时(主视图中唯一的视图是滚动视图),滚动会使大标题以比实际用手指滚动更快的速度消失。 (也就是说,如果我在屏幕上移动 2 厘米,滚动视图实际上滚动超过 2 厘米,直到大标题缩小到 'usual' 大小。)

下面是我的应用滚动的gif。我实际上移动得很少,它会自动向上滚动那么多。这不同于 Apple-made 应用程序(例如应用程序商店,显示在我的应用程序下方)。

有人有办法解决这种异常行为吗?

编辑: 根据请求,我正在添加当前的视图层次结构。我的代码中没有任何特别之处,我只是为 prefersLargeTitles 设置了标题和标志。

我已经调试了几天,找到了解决方法。

首先,发生了什么事?

UIScrollView 对 largeTitle 表现不佳。由于在导航栏变小的同时在滚动视图上向上滚动,因此与实际滚动相比存在两倍的滚动。

我通过有意设置确认了这一点:

scrollView.contentOffset.y = scrollView.contentOffset.y * 0.5

这确实让它如愿以偿。但是,这并不能解决整个问题,因为它在从大导航栏到小导航栏时没有产生平滑的过渡。您可以试试下面的代码。

if scrollView.contentOffset.y > 0 {
  if self.navigationController!.navigationBar.frame.size.height > 44.0 {
    scrollView.contentOffset.y = scrollView.contentOffset.y * 0.5
  }
}

这在缓慢滚动时有效'okay',但当您向下滑动时,它开始时动作缓慢(导航高度较大时),然后会加速。

解决方法

简而言之,您不能将 UIScrollView 与 iOS 11 大导航栏一起使用。您应该改用 UITableViewController
由于我的视图由多个垂直分布的水平 UICollectionViews 组成,因此我使用 UITableView 和不同的部分来形成使用故事板的 UI。 如果您使用 UITableViewController,它会按预期执行。
AppStore 和所有其他 Apple 制造的原生应用程序必须这样做。

我发现当导航栏有大标题并且不是半透明的时会发生这种情况。如果您使用的是 CollectionView 或 TableView,并且它被限制在安全区域或其父视图中,那么它应该为您处理插图。

对于滚动视图,请查看 Apple 文档,iOS11 中引入了一些用于安全区域更改的新变量(如 contentInsetAdjustmentBehavior): https://developer.apple.com/documentation/uikit/uiscrollview

使导航栏半透明

在 viewDidLoad() 中,尝试添加:

navigationController?.navigationBar.isTranslucent = true

或在 IB 中勾选:

translucent checkmark

我用这些约束解决了这个问题:

    NSLayoutConstraint.activate([
        scrollView.topAnchor.constraint(equalTo: view.topAnchor),
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor),
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor)
        ])

您还必须在 UIViewController 子类上设置此 属性:

extendedLayoutIncludesOpaqueBars = YES

双速情况下的问题可能是您的视图尺寸小于导航控制器视图尺寸并且您有类似的视图层次结构(您可以在视图调试器中检查它)

V:|-[navbar]-[view]-|

因此,当滚动时,您的视图框架会在内容偏移量更改期间发生变化,并且速度会加倍。

extendedLayoutIncludesOpaqueBars = true 应该有帮助。

我也发现了这个问题

在界面生成器中

  1. Select 你的 "viewController"
  2. 属性检查器勾选 "Under Opaque Bars" 和 "Under Top Bars"
  3. 将 scrollView 第二项的最高约束设置为 "SuperView" 而不是 "SafeArea"

首先确保scrollView的top constraints的第二项等于Superview.Top,而不是Safe Area.

其次,将这一行添加到您的视图控制器:extendedLayoutIncludesOpaqueBars = true。例如在 viewDidLoad.