it-swarm.com.ru

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

Я реализовал базовый UIViewController с UITableView, который обернут в UINavigationController. Я установил для prefersLargeTitles значение true:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    navigationController?.navigationBar.prefersLargeTitles = true
    navigationItem.title = "Coffees"
}

Тем не менее, заголовок остается маленьким, пока я не прокручиваю вид, и в этот момент он увеличивается. Я попытался переместить этот вызов туда, где я создаю UINavigationController, но эффекта не было. Я уверен, что навигационный контроллер не ноль, когда я устанавливаю prefersLargeTitles.

Должен ли я обновить это свойство в другом месте? Или я должен подать радар?

Обновление:

Кажется, что это происходит только в том случае, если мое представление содержит UITableView или само по себе UITableViewController

20
John Breen

У меня такая же проблема. Хотя вы не используете раскадровки, но я надеюсь, что это может кому-то помочь. Я установил флажок «Предпочитать большие заголовки» для контроллера навигации (не контроллера просмотра). Я встроил свой TableViewController. Все контроллеры представления после контроллера навигации развернулись и имели большие заголовки, и он должен работать. 

 

16
Paco Wong

У меня была такая же проблема только на одном столе ... 

Я должен был установить:

self.tableView.contentInsetAdjustmentBehavior = .never

так что мой просмотр таблицы перестает прокручиваться при загрузке uiviewcontroller.

Это автоматическая прокрутка таблицы, которая делает большой заголовок скрытым

Надеюсь это поможет

7
user1523505

Изменение contentInset tableView с помощью top:1 заставит NavigationBar развернуться и отобразить большие заголовки.

Obj-C,

-(void) viewWillAppear:(BOOL)animated {
    if (@available(iOS 11.0, *)) {
        tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0);
    }
}

Стриж

override func viewWillAppear(_ animated: Bool) {
    if #available(iOS 11.0, *) {
        tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0)
    }
}

Примечание: Если у вас есть tableView.reloadData() в вашем viewWillAppear, не забудьте вызвать его после редактирования contentInset

3
Pau Senabre

У меня была такая же проблема, и в моем случае оказалось, что структура раскадровки, которая работала в iOS 10 с Swift 3 (а также работает с iOS 11 с Swift 3), вызывала проблему на iOS 11 с Swift 4.

Разработать:

У меня в раскадровке был обычный UIViewController, для которого я установил подкласс UINavigationController (моя иерархия похожа на вашу, с подклассом UITabBarController → подкласс UINavigationController → подкласс UITableViewController).

В iOS 10 это работало нормально.

В iOS 11 это также отлично работает при запуске существующего приложения Swift 3.

Однако в приложении Swift 4, работающем на iOS 11, я видел те же симптомы, которые вы описали (большие заголовки появляются только при нажатии или прокрутке вниз).

Чтобы исправить это, я заменил элементы на основе UIViewController в раскадровке фактическими экземплярами UINavigationController (которые явно содержат UINavigationBar в раскадровке - у меня есть предчувствие, что суть проблемы заключается в том, что экземпляры UIViewController не имели этот элемент явно объявлен в раскадровке).

Во всяком случае, это решило проблему для меня.

Я запишу радар, так как он выглядит как регрессия на основе Swift 4, так как для меня он работает как в iOS 10 с Swift 3, так и в iOS 11 с Swift 3.

1
Aral Balkan

Общее изменение поведения navigationBar должно быть сделано в viewWillAppear(_:) 

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.prefersLargeTitles = true
}

После этого у меня все заработало.

1
BilalReffas

В моем случае решение состояло в том, чтобы установить верхнее выравнивание tableView в Безопасную область, а не Superview

1
Arnaud Dorgans

В раскадровке я установил для Large Title элемента навигации значение Never.

Navigation Item

В методе viewDidLoad моего ViewController я установил следующее:

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

Я столкнулся с той же проблемой и обнаружил, что обычно лучше установить свойство prefersLargeTitles из контроллера представления или объекта, который его устанавливает, и сделать это до его представления.

Например, если рассматриваемый контроллер представления отображается при запуске приложения:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    let window = UIWindow(frame: UIScreen.main.bounds)

    let someViewController: UIViewController = CustomViewController()

    let theNavController = UINavigationController(rootViewController: someViewController)
    theNavController.navigationBar.prefersLargeTitles = true

    window.rootViewController = theNavController
    window.makeKeyAndVisible()

    return true
}

или если представляет конкретный контроллер представления:

let someViewController: UIViewController = CustomViewController()

let theNavController = UINavigationController(rootViewController: someViewController)
theNavController.navigationBar.prefersLargeTitles = true

present(theNavController, animated: true, completion: nil)

Я нашел этот метод более надежным способом, чтобы гарантировать, что заголовок навигации отображается соответственно. Надеюсь это поможет! :)

1
gomollon

Я решил эту проблему через раскадровку

  1. Контроллер навигации -> Панель навигации -> Инспектор атрибутов -> Предпочитает большие заголовки (отмечено)
  2. Контроллер представления -> Элемент навигации -> Инспектор атрибутов -> Большой заголовок (автоматически или всегда отмечен)
1
yoAlex5

Подобная проблема для меня с добавлением UITableViewController к UIViewController. В моем случае эти контроллеры представления сами встроены в переменную UITabBarController, и только первая отображаемая вкладка правильно использовала большой заголовок. Для других вкладок требовалась ручная прокрутка перед отображением большого заголовка.

Единственное, что я смог получить на работе, это настроить contentInset согласно ответу @ pau-senabre, за исключением того, что вкладка top мне не помогла. Вместо этого я устанавливаю вставку left и затем сбрасываю ее при следующем цикле выполнения.

private var isFirstAppearance = true

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if isFirstAppearance {
        applyLargeTitlesFix()
    }
}

private func applyLargeTitlesFix() {
    let originalInset = tableViewController.tableView.contentInset
    tableViewController.tableView.contentInset = UIEdgeInsets(top: 0, left: 1, bottom: 0, right: 0)
    DispatchQueue.main.async { [weak self] in
        self?.tableViewController.tableView.contentInset = originalInset
    }
    isFirstAppearance = false
}
0
Ben Packard

У меня была похожая проблема. Представление является представлением таблицы. Свойство prefersLargeTitles установлено в событии viewDidLoad. Затем я установил заголовок представления в событии viewWillAppear.

override open func viewDidLoad() {
   if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.prefersLargeTitles = true
    } else {
        // Fallback on earlier versions
    }
    ...
}

override open func viewWillAppear(_ animated: Bool) {
    self.navigationItem.title = "something"
    ...
}

В моем событии подготовить переход я установил для элемента навигации значение nil, чтобы при следующем просмотре слева от элемента навигации var автоматически отображалось «Назад».

override func prepare(for segue: UIStoryboardSegue,
                      sender: Any?) {
    self.navigationItem.title = nil
    ...
}

В первый раз в табличном представлении правильно отображается большой заголовок. Однако если я выберу строку для следующего представления и возврата к представлению таблицы, заголовок элемента навигации станет пустым.

После нескольких часов борьбы я наконец узнал, что заголовок представления должен быть установлен в событии viewDidAppear! Кажется, что любой установленный для просмотра заголовка в событии Will будет сброшен UIKit внутренне обратно в ноль. Так что это должно быть установлено в другом событии.

override func viewDidAppear(_ animated: Bool) {
   self.navigationItem.title = "something"
   ...
}

override open func viewWillAppear(_ animated: Bool) {
    // self.navigationItem.title = "something" // Remove it and set title in Did event!
    ...
}

До того, как я представил эту новую функцию iOS 11, мое приложение работает нормально. Кажется, что новая функция имеет некоторые изменения в UIKit, так что приложению предыдущей версии могут потребоваться некоторые обновления/изменения, чтобы она работала.

0
David.Chu.ca

Поначалу это выглядит странно, но попробуйте установить navigationItem.largeTitleDisplayMode в always. По умолчанию automatic - и не определено, как это работает в docs .

Также написал/обновлю ответ о больших заголовках здесь .

0
kgaidis

У меня была та же проблема, и я исправил ее, изменив порядок представлений в моем ViewController в InterfaceBuilder. 

Кажется, что если первое представление в иерархии НЕ является ScrollView, то NavigationBar появляется в режиме LargeTitle и не анимируется вместе с представлением прокрутки. Если вам нужно иметь заголовок панели навигации, чтобы отразить прокрутку, то вам нужно поместить представление прокрутки как первое в иерархии представлений. 

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

0
egor

Недавно я столкнулся с той же проблемой, и ни одно из предложений не помогло мне. Вместо этого все, что мне нужно было сделать, это вызвать sizeToFit(). Образец кода:

private func configureNavigator() {
    guard let navigationController = navigationController else { return }
    navigationController.navigationBar.prefersLargeTitles = true
    navigationItem.largeTitleDisplayMode = .automatic
    navigationController.navigationBar.sizeToFit()
}

Надеюсь, это поможет!

0
titusmagnus

Еще одно возможное решение - завершить обновление в вашем refreshHandler (). как это-

@objc func refreshPage() {
    self.refreshControl?.endRefreshing() //End here
    self.loadTableData() //Get fresh data and reload table
}
0
ManjunathK

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

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

Это обратно совместимо с iOS 10 и не оставляет пустого места над первой строкой в ​​табличном представлении.

Я проверял prefersLargeTitle в инспекторе атрибутов контроллеров навигации только в IB - ничего в коде. То же самое для largeTitleDisplayMode = .always

Что касается того, почему это происходит с некоторыми контроллерами представления, а не с другими, я понятия не имею!

0
Ahmed Khedr

Та же проблема здесь с Swift 4.2, iOS 12 и переработанными раскадровками. 

Попытался добавить prefersLargeTitles = true в viewWillAppear и viewDidLoad, но ни одна из них не устранила мою проблему.

Вместо этого я скопировал переработанные раскадровки обратно в main.storyboard и нашел возможность включить большие заголовки в IB. Установите эту опцию, затем отредактируйте раскадровки, и теперь все работает. По какой-то причине первоначальный рефакторинг убрал опцию, и я не смог включить ее программно.

0
Rami