新しいアプリケーションにiOS 11ネイティブの大きなナビゲーションバータイトルを実装しようとしています。 viewDidLoad()で以下の関数を呼び出すことにより:
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationItem.largeTitleDisplayMode = .always
しかし、上にスクロールを開始すると(メインビュー内の唯一のビューはスクロールビューです)、スクロールすると、実際の指によるスクロールよりも速い速度で大きなタイトルが消えます。 (つまり、画面上で2cm移動すると、スクロールビューは実際には2cm以上スクロールし、大きなタイトルが「通常の」サイズに縮小するまで続きます。)
以下は、スクロールされるアプリのgifです。私は実際にはほとんど動かず、それだけ自動的に上にスクロールします。これはApple製のアプリケーション(たとえば、アプリの下に表示されるアプリストア)とは異なります。
誰かがこの異常な行動を解決する解決策を持っていますか?
編集:リクエストごとに、現在のビュー階層を追加しています。私のコードには特別なものはありません。prefersLargeTitles
のタイトルとフラグを設定するだけです。
私はこれを数日間デバッグしており、回避策を見つけました。
最初に、何が起こっていたのか?
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製ネイティブアプリは、この方法で行う必要があります。
これらの制約で問題を解決しました。
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
私もこの問題を見つけました。
インターフェイスビルダーで
これは、ナビゲーションバーに大きなタイトルがあり、半透明でないときに発生します。 CollectionViewまたはTableViewを使用しており、それが安全な領域またはそのスーパービューに制限されている場合、インセットを処理する必要があります。
スクロールビューについては、iOSで導入されたセーフエリアの変更について、Apple docs、contentInsetAdjustmentBehaviorなど)の新しい変数があります。 11: https://developer.Apple.com/documentation/uikit/uiscrollview
ナビゲーションバーを半透明にするには
ViewDidLoad()で、追加してみてください:
navigationController?.navigationBar.isTranslucent = true
または、IBでこのチェックマークを設定します。
倍速の場合の問題は、ビューのサイズがNavigation Controllerのビューのサイズよりも小さく、ビューの階層が似ていることです(ビューデバッガで確認できます)
V:|-[navbar]-[view]-|
したがって、コンテンツオフセットの変更中にビューのフレームをスクロールすると、速度が2倍になります。
extendedLayoutIncludesOpaqueBars = true
が役立つはずです。