iOS 11 большая навигационная панель название неожиданная скорость

Я пытаюсь реализовать основной заголовок навигационной панели iOS 11 в своем новом приложении. Вызов ниже функций в viewDidLoad():

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

Я получаю то, что желаю. enter image description here

Но, когда я начинаю прокручивать (единственный вид внутри основного вида - это прокрутка), прокрутка делает большой заголовок исчезающим с большей скоростью, чем фактический прокрутка пальцем. (т.е. если я перемещаю 2 см на экране, просмотр прокрутки фактически прокручивается более чем на 2 см до тех пор, пока большой заголовок не уменьшится до "обычного" размера.)

Ниже приведен пример gif моего приложения. Я на самом деле очень мало передвигаюсь, и он автоматически прокручивается так сильно. Это отличается от приложений Apple (например, магазина приложений, показанного ниже моего приложения).

У кого-нибудь есть решение для решения этого ненормального поведения?

enter image description here

enter image description here

EDIT: по запросу я добавляю текущую иерархию View. В моем коде нет ничего особенного, я просто установил заголовок и флаг для prefersLargeTitles.

enter image description here

Ответы

Ответ 1

Я отлаживал это на пару дней, и я нашел обходное решение.

Во-первых, что было дальше?

UIScrollView не очень хорошо работает с большим титром. Поскольку в режиме прокрутки просматривается прокрутка одновременно с уменьшением полосы навигации, в два раза больше прокрутки по сравнению с фактическим прокруткой.

Я подтвердил это, преднамеренно установив:

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

Это срабатывало "нормально" при прокрутке медленно, но когда вы бросаете вниз, сначала он действует медленно (в то время как высота навигации велика), а затем ускоряется позже.

Временное решение

Проще говоря, вы НЕ МОЖЕТЕ использовать UIScrollView с большой навигационной панелью iOS 11. Вместо этого вы должны использовать UITableViewController.
Поскольку мой взгляд состоит из нескольких горизонтальных UICollectionViews расположенных по вертикали, я использовал UITableView с различными разделами для формирования пользовательского интерфейса с помощью раскадровки. Если вы используете UITableViewController, он выполняет по желанию.
AppStore и все другие приложения, созданные Apple, должны делать это таким образом.

Ответ 2

Я решил проблему с этими ограничениями:

    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

Ответ 3

Я тоже нашел эту проблему.

В интерфейсе Builder

  1. Выберите свой "viewController"
  2. Атрибут Inspector tick "Под непрозрачными барами" и "Under Top Bars"
  3. Сделайте свои верхние ограничения вашего второго элемента scrollView для "SuperView", а не "SafeArea"

Ответ 4

Я обнаружил, что это происходит, когда панель навигации имеет большие заголовки и не является полупрозрачной. Если вы используете CollectionView или TableView, и он ограничен безопасной областью или ее супервидом, тогда он должен обрабатывать вставки для вас.

Для просмотра прокрутки просмотрите документы Apple, есть несколько новых переменных (например, contentInsetAdjustmentBehavior) для безопасных изменений области, которые были введены в iOS 11: https://developer.apple.com/documentation/uikit/uiscrollview

Чтобы сделать панель навигации прозрачной

В viewDidLoad() попробуйте добавить:

navigationController?.navigationBar.isTranslucent = true

Или установите этот флажок в IB:

полупрозрачная галочка

Ответ 5

Проблема в случае двойной скорости может заключаться в том, что размер вашего представления меньше, чем размер представления контроллера навигации, и у вас есть просмотр типа hierarhy (вы можете проверить его в режиме отладки)

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

поэтому при прокрутке рамки просмотра меняется при изменении смещения содержимого, и он удваивает скорость.

extendedLayoutIncludesOpaqueBars = true должно помочь.

Ответ 6

Прежде всего, убедитесь, что второй элемент верхних ограничений scrollView равен Superview.Top, а не Safe Area.

Во-вторых, добавьте эту строку в ваш контроллер вида: extendedLayoutIncludesOpaqueBars = true. Например, в viewDidLoad.