bar - iOS 11 prefersLargeTitles no se actualiza hasta que se desplaza
uisearchbar swift 4 (15)
Implementé un UIViewController básico con un UITableView que está envuelto en un UINavigationController. Puse prefersLargeTitles
en 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"
}
Sin embargo, el título permanece pequeño hasta que desplazo la vista, en cuyo punto se amplía. Intenté mover esa llamada a donde creo el UINavigationController, pero no hubo ningún efecto. Estoy seguro de que navigationController no es nulo cuando configuro prefersLargeTitles
.
¿Debo actualizar esa propiedad en otro lugar? ¿O debería presentar un radar?
Actualizar:
Esto solo parece suceder si mi vista contiene un UITableView
o si es un UITableViewController
Acabo de tener este mismo problema y, en mi caso, resulta que la estructura del Storyboard que funcionaba en iOS 10 con Swift 3 (y también funciona con iOS 11 con Swift 3) estaba causando el problema en iOS 11 con Swift 4.
Elaborar:
Tenía un UIViewController regular en mi guión gráfico que había establecido en una subclase UINavigationController (mi jerarquía es similar a la suya, con la subclase UITabBarController → subclase UINavigationController → subclase UITableViewController).
En iOS 10, esto funcionó bien.
En iOS 11, esto también funciona bien cuando ejecuta la aplicación Swift 3 existente.
Sin embargo, con la aplicación Swift 4, que se ejecuta en iOS 11, estaba viendo los mismos síntomas que describió (los títulos grandes solo aparecen cuando se tira de la vista hacia abajo).
Para solucionarlo, reemplacé los elementos basados en UIViewController en el Storyboard con instancias reales de UINavigationController (que contienen una barra de UINavigation explícitamente en el Storyboard. ese elemento declarado explícitamente dentro del Storyboard).
De todos modos, eso me solucionó el problema.
Archivaré el radar ya que parece una regresión basada en Swift 4, ya que, para mí, funciona tanto en iOS 10 con Swift 3 como en iOS 11 con Swift 3.
El cambio general del comportamiento de la viewWillAppear(_:)
navigationBar
debe hacer en viewWillAppear(_:)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.prefersLargeTitles = true
}
Después de hacer eso funcionó bien para mí.
En el guión gráfico, establezco el Large Title
del elemento de navegación en Never
.
En el método viewDidLoad de mi ViewController, establezco lo siguiente:
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
En mi caso, la solución fue establecer la alineación superior de tableView con el área segura y no con Superview
Eso parece ser un comportamiento extraño al principio, pero intente configurar el elemento navigationItem.largeTitleDisplayMode
como always
. El valor predeterminado es automatic
, y no está definido cómo funciona en los docs .
También escribí / actualizaré una respuesta sobre títulos grandes here .
He perdido una cantidad considerable de tiempo en esto, ya que la saga prefersLargeTitle
funciona en algunos controladores de vista como se esperaba y con algunos produce el mismo problema anterior.
La solución para mí fue desmarcar los bordes extendidos debajo de las barras superiores en IB: para aquellos controladores de vista que muestran títulos grandes momentáneamente hasta que se cargan los contenidos de la vista de tabla, luego la barra de navegación vuelve a su tamaño normal. Solo muestra el título grande cuando se desplaza la vista de tabla hacia abajo.
Esto es compatible con versiones anteriores de iOS 10 y no deja ningún espacio vacío sobre la primera fila en la vista de tabla.
Había marcado prefersLargeTitle
en el inspector de atributos de los controladores de navegación solo en IB - nada en el código. Lo mismo para largeTitleDisplayMode = .always
En cuanto a por qué sucede esto con algunos controladores de vista y no con otros, ¡no tengo absolutamente ninguna idea!
La modificación del contentInset del tableView con top:1
forzará la barra de navegación para expandir y mostrar los títulos grandes.
Obj-c
-(void) viewWillAppear:(BOOL)animated {
if (@available(iOS 11.0, *)) {
tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0);
}
}
Rápido
override func viewWillAppear(_ animated: Bool) {
if #available(iOS 11.0, *) {
tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0)
}
}
Nota: Si tiene un tableView.reloadData()
en su viewWillAppear
asegúrese de llamarlo después de editar el contentInset
Me encontré con el mismo problema y encontré que generalmente es mejor establecer la propiedad prefersLargeTitles
desde el controlador de la vista o el objeto que lo configura, y hacerlo antes de que se presente.
Por ejemplo, si el controlador de vista en cuestión se muestra al iniciar la aplicación:
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
}
o si presenta un controlador de vista particular:
let someViewController: UIViewController = CustomViewController()
let theNavController = UINavigationController(rootViewController: someViewController)
theNavController.navigationBar.prefersLargeTitles = true
present(theNavController, animated: true, completion: nil)
Descubrí que este método es una forma más segura de asegurar que el título de navegación se muestre en consecuencia. ¡Espero que esto ayude! :)
Recientemente tuve el mismo problema y ninguna de las sugerencias funcionó para mí. En su lugar, todo lo que tenía que hacer era invocar sizeToFit()
. Código de muestra:
private func configureNavigator() {
guard let navigationController = navigationController else { return }
navigationController.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .automatic
navigationController.navigationBar.sizeToFit()
}
¡Espero que esto ayude!
Tuve el mismo problema solo en una vista de tabla ...
Tuve que poner:
self.tableView.contentInsetAdjustmentBehavior = .never
para que mi vista de tabla deje de desplazarse cuando se haya cargado uiviewcontroller.
Es el desplazamiento automático de Tableview lo que hace que el título grande se oculte.
Espero que esto ayude
Tuve el mismo problema y lo solucioné cambiando el orden de las vistas en mi ViewController en InterfaceBuilder.
Parece que si la primera vista en Jerarquía NO es una vista de desplazamiento, entonces la barra de navegación aparece en el modo de título grande y no se anima junto con la vista de desplazamiento. Si necesita tener el título de la barra de navegación para reflejar su desplazamiento, entonces debe colocar su vista de desplazamiento como la primera en la jerarquía de vistas.
Además, no estoy completamente seguro de esto, pero parece que el aspecto de la barra de navegación en el modo estándar o de título grande depende de las jerarquías de vistas del controlador anterior.
Tuve el mismo problema. La vista es una vista de tabla. La propiedad de prefersLargeTitles
se establece en el evento viewDidLoad
. Luego configuro el título de la vista en el evento 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"
...
}
En el evento de preparación de mi evento, configuré el mosaico del elemento de navegación en nil
para que la siguiente vista del elemento de navegación de la izquierda muestre "Atrás" automáticamente.
override func prepare(for segue: UIStoryboardSegue,
sender: Any?) {
self.navigationItem.title = nil
...
}
La primera vez que la vista de tabla muestra el título grande correctamente. Sin embargo, si selecciono una fila para la siguiente vista y vuelvo a la vista de tabla, el título del elemento de navegación queda vacío.
Después de varias horas de lucha, finalmente descubro que el título de la vista se debe establecer en el evento viewDidAppear
. Parece que cualquiera que esté configurado para ver el título en Will
evento Will
será restablecido por UIKit internamente a cero. Por lo tanto, tiene que ser establecido en un evento diferente.
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!
...
}
Antes de presentar esta nueva característica de iOS 11, mi aplicación funciona bien. Parece que la nueva característica tiene algunos cambios en UIKit, por lo que la aplicación de la versión anterior puede necesitar algunas actualizaciones / cambios para que funcione.
Un problema similar para mí con un UITableViewController
agregado a un UIViewController
. En mi caso, estos controladores de vista están incrustados en un UITabBarController
y solo la primera pestaña que se muestra correctamente usa un título grande. Otras pestañas requerían un desplazamiento manual antes de que se mostrara el título grande.
Lo único con lo que pude ponerme a trabajar fue ajustar el contentInset
según la respuesta de @pau-senabre, excepto que la top
recuadro no fue útil para mí. En su lugar, establezco la inserción left
y luego la reinicio en el próximo runloop.
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
}
Una solución más posible es finalizar la actualización en refreshHandler (). Me gusta esto-
@objc func refreshPage() {
self.refreshControl?.endRefreshing() //End here
self.loadTableData() //Get fresh data and reload table
}
Yo tuve el mismo problema. Aunque no estés usando Storyboards, espero que esto pueda ayudar a alguien. Marqué "Preferir Títulos Grandes" para el Controlador de Navegación (no el Controlador de Vista). Embebí mi TableViewController en. Todos los Controladores de Vista después de que el Controlador de Navegación giró y tenía títulos grandes, debería funcionar.