J'ai implémenté un UIViewController de base avec un UITableView encapsulé dans un UINavigationController. J'ai mis 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"
}
Cependant, le titre reste petit jusqu'à ce que je fasse défiler la vue, puis l'élargit. J'ai essayé de déplacer cet appel à l'endroit où je crée UINavigationController, mais cela n'a eu aucun effet. Je suis sûr que le contrôle de navigation n’est pas à zéro lorsque j’ai défini prefersLargeTitles
.
Devrais-je mettre à jour cette propriété ailleurs? Ou devrais-je déposer un radar?
Mettre à jour:
Cela ne semble se produire que si ma vue contient une UITableView
ou est elle-même une UITableViewController
J'ai eu le même problème. Bien que vous n'utilisiez pas de Storyboards, j'espère que cela pourrait aider quelqu'un. J'ai coché "Préférer les grands titres" pour le contrôleur de navigation (et non le contrôleur de vue) dans lequel j'ai intégré mon contrôleur ViewView. Tous les contrôleurs de vue après que le contrôleur de navigation ait tourné et avait de gros titres, et cela devrait fonctionner.
J'ai eu le même problème que sur une tableview ...
Je devais mettre:
self.tableView.contentInsetAdjustmentBehavior = .never
de sorte que ma vue de table cesse de défiler lorsque uiviewcontroller est chargé.
C'est le défilement automatique de la table qui fait que le gros titre est masqué
J'espère que cela t'aides
La modification de contentInset de tableView avec top:1
force la barre de navigation à se développer et à afficher les gros titres.
Obj-C
-(void) viewWillAppear:(BOOL)animated {
if (@available(iOS 11.0, *)) {
tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0);
}
}
Rapide
override func viewWillAppear(_ animated: Bool) {
if #available(iOS 11.0, *) {
tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0)
}
}
Remarque: Si vous avez une tableView.reloadData()
dans votre viewWillAppear
, assurez-vous de l'appeler après avoir modifié la contentInset
Je viens d'avoir le même problème et, dans mon cas, il s'avère que la structure Storyboard qui fonctionnait dans iOS 10 avec Swift 3 (et fonctionne également avec iOS 11 avec Swift 3) était à l'origine du problème sur iOS 11 avec Swift 4.
Élaborer:
J'avais un UIViewController normal dans mon storyboard que j'avais défini sur une sous-classe UINavigationController (ma hiérarchie est similaire à la vôtre, avec la sous-classe UITabBarController → la sous-classe UINavigationController → la sous-classe UITableView.
Dans iOS 10, cela a bien fonctionné.
Dans iOS 11, cela fonctionne également bien lorsque vous exécutez l'application Swift 3 existante.
Cependant, avec l'application Swift 4, fonctionnant sur iOS 11, je voyais les mêmes problèmes que vous avez décrits (les gros titres n'apparaissent que lorsque vous déroulez/faites défiler la vue).
Pour résoudre ce problème, j'ai remplacé les éléments basés sur UIViewController dans le Storyboard par des occurrences réelles d'UINavigationController (qui contiennent explicitement un UINavigationBar dans le Storyboard. J'ai l'intuition que le nœud du problème provient de ce que les instances d'UIViewController n'avaient cet élément explicitement déclaré dans le Storyboard).
Quoi qu'il en soit, cela a résolu le problème pour moi.
Je vais enregistrer le radar car cela ressemble à une régression basée sur Swift 4, car pour moi, cela fonctionne à la fois sous iOS 10 avec Swift 3 et sous iOS 11 avec Swift 3.
Le changement général du comportement de la navigationBar
doit être fait en viewWillAppear(_:)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.prefersLargeTitles = true
}
Après cela, cela a bien fonctionné pour moi.
Dans mon cas, la solution consistait à définir l'alignement supérieur de tableView sur Zone sécurisée et non sur Superview.
Dans le storyboard, je règle Large Title
de l'élément de navigation sur Never
.
Dans la méthode viewDidLoad de mon ViewController, je définis ce qui suit:
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
J’ai rencontré le même problème et découvert qu’il était généralement préférable de définir la propriété prefersLargeTitles
à partir du contrôleur de vue ou de l’objet qui le configure et de le faire avant sa présentation.
Par exemple, si le contrôleur de vue en question est affiché au lancement de l'application:
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
}
ou si vous présentez un contrôleur de vue particulier:
let someViewController: UIViewController = CustomViewController()
let theNavController = UINavigationController(rootViewController: someViewController)
theNavController.navigationBar.prefersLargeTitles = true
present(theNavController, animated: true, completion: nil)
J'ai trouvé que cette méthode était un moyen plus sûr de s'assurer que le titre de la navigation est affiché en conséquence. J'espère que cela t'aides! :)
J'ai résolu ce problème via le storyboard
Problème similaire pour moi avec un UITableViewController
ajouté à un UIViewController
. Dans mon cas, ces contrôleurs de vue sont eux-mêmes incorporés dans une UITabBarController
et seul le premier onglet affiché utilisait correctement un grand titre. Les autres onglets nécessitaient un défilement manuel avant l'affichage du titre de grande taille.
La seule chose que je pouvais faire au travail était d’ajuster la contentInset
selon la réponse de @pau-senabre, sauf que la top
ne me servait à rien. Au lieu de cela, j'ai défini l'insertion left
, puis je l'ai réinitialisé lors du prochain cycle d'exécution.
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
}
J'ai eu le même problème. La vue est une vue de table. La propriété de prefersLargeTitles
est définie sur viewDidLoad
event. Ensuite, j'ai défini le titre de la vue dans l'événement 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"
...
}
Dans mon événement prepare segue, j’ai défini la vignette de l’élément de navigation sur nil
de sorte que l’élément de navigation à gauche suivant de la vue suivante affiche «Retour» automatiquement.
override func prepare(for segue: UIStoryboardSegue,
sender: Any?) {
self.navigationItem.title = nil
...
}
La première fois que la vue tabulaire affiche un grand titre correctement. Cependant, si je sélectionne une ligne dans la vue suivante et revient à la vue sous forme de tableau, le titre de l'élément de navigation devient vide.
Après plusieurs heures de lutte, je découvre enfin que le titre de la vue doit être défini dans l'événement viewDidAppear
! Il semble que tout ce qui est défini pour afficher le titre de la vue dans l'événement Will
serait réinitialisé en interne par UIKit à nouveau à zéro. Donc, il doit être réglé dans un autre événement.
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!
...
}
Avant d’introduire cette nouvelle fonctionnalité iOS 11, mon application fonctionne correctement. Il semble que la nouvelle fonctionnalité comporte quelques modifications dans UIKit, de sorte que la version précédente de l'application peut nécessiter des mises à jour/modifications pour la rendre opérationnelle.
J'avais le même problème et je l'ai corrigé en modifiant l'ordre des vues dans ViewController dans InterfaceBuilder.
Il semble que si la première vue dans la hiérarchie n'est PAS une vue de défilement, alors NavigationBar apparaît en mode Large Titre et ne s'anime pas avec la vue de défilement. Si vous avez besoin que le titre de la barre de navigation reflète votre défilement, vous devez placer la vue de défilement en premier dans la hiérarchie.
De plus, je ne suis pas tout à fait sûr à ce sujet, mais l'apparence de la barre de navigation en mode Titre standard ou Titre large dépend de la hiérarchie des vues du contrôleur précédent.
J'ai récemment abordé le même problème et aucune des suggestions n'a fonctionné pour moi. Au lieu de cela, tout ce que j'avais à faire était d'invoquer sizeToFit()
. Exemple de code:
private func configureNavigator() {
guard let navigationController = navigationController else { return }
navigationController.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .automatic
navigationController.navigationBar.sizeToFit()
}
J'espère que ça aide!
Une autre solution possible consiste à mettre fin à l'actualisation dans votre refreshHandler (). comme ça-
@objc func refreshPage() {
self.refreshControl?.endRefreshing() //End here
self.loadTableData() //Get fresh data and reload table
}
J'ai perdu beaucoup de temps à ce sujet, car la saga prefersLargeTitle
fonctionne sur certains contrôleurs de vue comme prévu et avec certains, elle produit le même problème que ci-dessus.
La solution pour moi était de décocher Extended Edges Under Top Bar dans IB - pour les contrôleurs de vue qui affichent momentanément les gros titres jusqu'à ce que le contenu de la vue tableau soit chargé, puis la barre de navigation revient à la taille normale. Il ne montre que le gros titre lorsque vous faites défiler la vue tableau vers le bas.
Ceci est rétro-compatible avec iOS 10 et ne laisse aucun espace vide au-dessus de la première ligne de la vue tableau.
J'avais vérifié prefersLargeTitle
dans l'inspecteur des attributs des contrôleurs de navigation uniquement dans IB - rien dans le code. Idem pour largeTitleDisplayMode = .always
Quant à savoir pourquoi cela se produit avec certains contrôleurs de vue et pas d'autres, je n'en ai aucune idée!
Programmation:
Dans AppDelegate.Swift:
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let navigationController = UINavigationController.init(rootViewController: ViewController())
window?.rootViewController = navigationController
Dans ViewController:
remplacer func viewWillAppear (_ animé: Bool) {super.viewWillAppear (animé)
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .automatic
}
remplacer func loadView () {super.loadView ()
view.addSubview(tableView)
view.addSubview(loadingView)
NSLayoutConstraint.activate([
tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
tableView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor),
tableView.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor)
])
}
VÉRIFIEZ QUE VOTRE VUE À TABLE A ÉTÉ AJOUTÉE À VOTRE VUE _ AT FIRST!
Même problème ici avec Swift 4.2, iOS 12 et les Storyboards refactorisés.
J'ai essayé d'ajouter prefersLargeTitles = true
à viewWillAppear
et viewDidLoad
, mais ni l'un ni l'autre n'a résolu le problème.
Au lieu de cela, j'ai copié les story-boards refactorisés dans main.storyboard et trouvé l'option d'activer les gros titres dans IB. Définissez cette option, puis refactorisez les storyboards et tout fonctionne maintenant. Pour une raison quelconque, la refactorisation initiale a supprimé l'option et je ne pouvais pas l'activer par programme.