web-dev-qa-db-ja.com

iOS 11の大きなナビゲーションバータイトルの予想外の速度

新しいアプリケーションにiOS 11ネイティブの大きなナビゲーションバータイトルを実装しようとしています。 viewDidLoad()で以下の関数を呼び出すことにより:

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

欲しいものが手に入ります。 enter image description here

しかし、上にスクロールを開始すると(メインビュー内の唯一のビューはスクロールビューです)、スクロールすると、実際の指によるスクロールよりも速い速度で大きなタイトルが消えます。 (つまり、画面上で2cm移動すると、スクロールビューは実際には2cm以上スクロールし、大きなタイトルが「通常の」サイズに縮小するまで続きます。)

以下は、スクロールされるアプリのgifです。私は実際にはほとんど動かず、それだけ自動的に上にスクロールします。これはApple製のアプリケーション(たとえば、アプリの下に表示されるアプリストア)とは異なります。

誰かがこの異常な行動を解決する解決策を持っていますか?

enter image description here

enter image description here

編集:リクエストごとに、現在のビュー階層を追加しています。私のコードには特別なものはありません。prefersLargeTitlesのタイトルとフラグを設定するだけです。

enter image description here

35
Seop Yoon

私はこれを数日間デバッグしており、回避策を見つけました。

最初に、何が起こっていたのか?

LargeTitleでうまく機能しないのはUIScrollViewです。ナビゲーションバーが小さくなると同時にスクロールビューが上にスクロールするため、実際のスクロールと比較して2倍のスクロールが存在します。

私は意図的に設定してこれを確認しました:

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
  }
}

これは、ゆっくりスクロールすると「大丈夫」に機能しましたが、下に飛び込むと、最初はゆっくりと動作し(ナビゲーションの高さが大きい間)、その後は高速化します。

[〜#〜]回避策[〜#〜]

簡単に言えば、iOS 11の大きなナビゲーションバーではUIScrollViewを使用できません。代わりにUITableViewControllerを使用する必要があります。
私のビューは垂直方向に広がる複数の水平UICollectionViewsで構成されているため、異なるセクションでUITableViewを使用して、ストーリーボードを使用してUIを形成しました。 UITableViewControllerを使用すると、必要に応じて実行されます。
AppStoreおよび他のすべてのApple製ネイティブアプリは、この方法で行う必要があります。

8
Seop Yoon

これらの制約で問題を解決しました。

    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
37
Roman

私もこの問題を見つけました。

インターフェイスビルダーで

  1. 「viewController」を選択します
  2. 属性インスペクターティック「不透明バーの下」および「上部バーの下」
  3. ScrollViewの2番目のアイテムの最上位の制約を「SafeArea」ではなく「SuperView」にします。
21
user8637708

これは、ナビゲーションバーに大きなタイトルがあり、半透明でないときに発生します。 CollectionViewまたはTableViewを使用しており、それが安全な領域またはそのスーパービューに制限されている場合、インセットを処理する必要があります。

スクロールビューについては、iOSで導入されたセーフエリアの変更について、Apple docs、contentInsetAdjustmentBehaviorなど)の新しい変数があります。 11: https://developer.Apple.com/documentation/uikit/uiscrollview

ナビゲーションバーを半透明にするには

ViewDidLoad()で、追加してみてください:

navigationController?.navigationBar.isTranslucent = true

または、IBでこのチェックマークを設定します。

半透明のチェックマーク

6
JWhitey

倍速の場合の問題は、ビューのサイズがNavigation Controllerのビューのサイズよりも小さく、ビューの階層が似ていることです(ビューデバッガで確認できます)

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

したがって、コンテンツオフセットの変更中にビューのフレームをスクロールすると、速度が2倍になります。

extendedLayoutIncludesOpaqueBars = trueが役立つはずです。

5
Artjom Bastun