wake-up-neo.com

iOS 11 bevorzugt, dass die Titel nicht aktualisiert werden

Ich habe einen einfachen UIViewController mit einer UITableView implementiert, die in einem UINavigationController eingeschlossen ist. Ich setze prefersLargeTitles auf 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"
}

Der Titel bleibt jedoch so lange klein, bis ich die Ansicht scrollen und dann vergrößern kann. Ich habe versucht, den Aufruf dahin zu verschieben, wo ich den UINavigationController erstellt habe, aber es gab keinen Effekt. Ich bin sicher, dass der navigationController nicht null ist, wenn ich prefersLargeTitles setze.

Sollte ich diese Eigenschaft an anderer Stelle aktualisieren? Oder soll ich ein Radar einreichen?

Update:

Dies scheint nur zu passieren, wenn meine Ansicht eine UITableView enthält oder selbst eine UITableViewController ist.

20
John Breen

Ich hatte das gleiche Problem. Sie verwenden zwar keine Storyboards, aber ich hoffe, das könnte jemandem helfen. Ich habe das Kontrollkästchen "Große Titel bevorzugen" für den Navigations-Controller (nicht den View Controller) aktiviert. Ich habe meinen TableViewController eingebettet. Alle View-Controller, nachdem der Navigations-Controller gedreht wurde, hatten große Titel, und es sollte funktionieren. 

 

16
Paco Wong

Ich hatte das gleiche Problem nur auf einem Tableview ... 

Ich musste einstellen:

self.tableView.contentInsetAdjustmentBehavior = .never

so dass mein tableview aufhört zu scrollen, wenn uiviewcontroller geladen wurde.

Durch das automatische Scrollen in der Tabellenansicht wird der große Titel ausgeblendet

Hoffe das hilft

7
user1523505

Wenn Sie das contentInset der tableView mit top:1 ändern, wird die Navigationsleiste dazu gezwungen, die großen Titel zu erweitern und anzuzeigen.

Obj-C

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

Schnell

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

Hinweis: Wenn Sie eine tableView.reloadData() in Ihrer viewWillAppear haben, rufen Sie sie unbedingt nach der Bearbeitung der contentInset auf.

3
Pau Senabre

Ich hatte gerade das gleiche Problem und in meinem Fall stellt sich heraus, dass die Storyboard-Struktur, die in iOS 10 mit Swift 3 (und auch mit iOS 11 mit Swift 3) funktioniert, das Problem auf iOS 11 mit Swift 4 verursacht hat.

Um auszuarbeiten:

Ich hatte einen normalen UIViewController in meinem Storyboard, den ich auf eine UINavigationController-Unterklasse gesetzt hatte (meine Hierarchie ähnelt Ihrer, mit UITabBarController-Unterklasse → UINavigationController-Unterklasse → UITableViewController-Unterklasse → UITableViewController-Unterklasse).

In iOS 10 hat dies gut funktioniert.

In iOS 11 funktioniert dies auch gut, wenn Sie die vorhandene Swift 3-App ausführen.

Bei der Swift 4-App unter iOS 11 wurden jedoch dieselben Symptome angezeigt, die Sie beschrieben haben (große Titel werden nur angezeigt, wenn Sie die Ansicht nach unten ziehen/scrollen).

Um das Problem zu beheben, habe ich die UIViewController-basierten Elemente im Storyboard durch tatsächliche UINavigationController-Instanzen ersetzt (die explizit eine UINavigationBar im Storyboard enthalten. Ich habe eine Vermutung, dass hier der Kern des Problems liegt, da die UIViewController-Instanzen nicht vorhanden waren das im Storyboard explizit deklarierte Element).

Wie auch immer, das hat das Problem für mich behoben.

Ich werde Datei-Radar erstellen, da dies wie eine auf Swift 4 basierende Regression aussieht, da es für mich sowohl unter iOS 10 mit Swift 3 als auch unter iOS 11 mit Swift 3 funktioniert.

1
Aral Balkan

Generell sollte das Verhalten der navigationBar in viewWillAppear(_:) geändert werden. 

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

Danach funktionierte es gut für mich.

1
BilalReffas

Ich denke, es scheint ein bisschen blöd zu sein, aber ich habe das Problem damit effektiv gelöst:

self.navigationItem.Prompt = ""

self.navigationItem.Prompt = nil

Es ist, als ob navigationBar eine Art Update in einem seiner Elemente benötigt, um das Layout zu aktualisieren.

Manchmal muss ich etwas in der Navigationsleiste ein- und ausblenden, um es zu aktualisieren. Deshalb gibt es meiner Meinung nach die beste Möglichkeit, dies zu tun. Im Moment ist das meine Problemumgehung.

1

In meinem Fall bestand die Lösung darin, die oberste Ausrichtung von tableView auf den sicheren Bereich und nicht auf Superview festzulegen

1
Arnaud Dorgans

Im Storyboard habe ich den Large Title des Navigationselements auf Never gesetzt.

Navigation Item

In der viewDidLoad-Methode meines ViewControllers habe ich Folgendes festgelegt:

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

Ich bin auf das gleiche Problem gestoßen und habe festgestellt, dass es in der Regel am besten ist, die prefersLargeTitles -Eigenschaft von dem View-Controller oder dem Objekt, das ihn einrichtet, festzulegen, und dies vor der Präsentation zu tun.

Wenn zum Beispiel der betreffende View Controller beim Start der App angezeigt wird:

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
}

oder wenn Sie einen bestimmten View-Controller präsentieren:

let someViewController: UIViewController = CustomViewController()

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

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

Ich fand diese Methode eine sicherere Methode, um sicherzustellen, dass der Navigationstitel entsprechend angezeigt wird. Hoffe das hilft! :)

1
gomollon

Ich habe dieses Problem per Storyboard gelöst

  1. Navigationscontroller -> Navigationsleiste -> Eigenschafteninspektor -> Präferiert große Titel (markiert)
  2. View Controller -> Navigationselement -> Eigenschafteninspektor -> Großer Titel (Automatisch oder Immer markiert)
1
yoAlex5

Ähnliches Problem für mich mit einer UITableViewController, die einer UIViewController hinzugefügt wurde. In meiner Instanz sind diese Ansichtscontroller selbst in eine UITabBarController eingebettet, und nur die erste Registerkarte, die korrekt angezeigt wird, verwendet einen großen Titel. Bei anderen Registerkarten war ein manueller Bildlauf erforderlich, bevor der große Titel angezeigt wurde.

Das Einzige, was ich zur Arbeit bekommen konnte, war, die contentInset entsprechend der Antwort von @ pau-senabre anzupassen, außer dass der top-Einsatz für mich nicht hilfreich war. Stattdessen setze ich die left-Einfügung und setze sie dann beim nächsten Runloop zurück.

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

Ich hatte das ähnliche Problem. Die Ansicht ist eine Tabellenansicht. Die Eigenschaft von prefersLargeTitles wird auf viewDidLoad event gesetzt. Dann habe ich den View-Titel in viewWillAppear gesetzt.

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

In meinem Vorbereitungssegmentereignis setze ich die Kachel des Navigationselements auf nil, sodass das Navigationselement der nächsten Ansicht links links automatisch "Zurück" anzeigt.

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

Wenn die Tabellenansicht zum ersten Mal richtig angezeigt wird, wird der große Titel korrekt angezeigt. Wenn ich jedoch eine Zeile für die nächste Ansicht und zurück zur Tabellenansicht auswähle, wird der Titel des Navigationselements leer.

Nach einigen stundenlangen Schwierigkeiten finde ich endlich heraus, dass der Titel der Ansicht in viewDidAppear gesetzt sein sollte! Es scheint, dass das, was in Will für den Titel der Ansicht festgelegt wurde, von UIKit intern auf null zurückgesetzt wird. Es muss also auf ein anderes Ereignis eingestellt werden.

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

Bevor ich dieses neue iOS 11-Feature einführte, läuft meine App in Ordnung. Es scheint, dass die neue Funktion einige Änderungen in UIKit vorgenommen hat, sodass die App der vorherigen Version möglicherweise einige Updates/Änderungen benötigt, damit sie funktioniert.

0
David.Chu.ca

Das scheint auf den ersten Blick ein seltsames Verhalten zu sein, aber setzen Sie navigationItem.largeTitleDisplayMode auf always. Die Standardeinstellung ist automatic - und es ist nicht definiert, wie dies in docs funktioniert.

Auch schrieb/wird eine Antwort auf große Titel hier aktualisieren.

0
kgaidis

Ich hatte das gleiche Problem und es wurde behoben, indem die Reihenfolge der Ansichten in meinem ViewController in InterfaceBuilder geändert wurde. 

Wenn die erste Ansicht in Hierarchie KEINE ScrollView ist, wird die Navigationsleiste im LargeTitle-Modus angezeigt und nicht zusammen mit der Scroll-Ansicht animiert. Wenn Sie den Titel der Navigationsleiste verwenden müssen, um den Bildlauf anzuzeigen, müssen Sie die Bildlaufansicht als erste Ansichtshierarchie einfügen. 

Ich bin auch nicht ganz sicher, aber das Aussehen der Navigationsleiste im Standard- oder Large Title-Modus hängt von der Ansichtshierarchie des vorherigen Controllers ab. 

0
egor

Ich habe vor kurzem das gleiche Thema gefunden und keiner der Vorschläge hat für mich funktioniert. Stattdessen musste ich lediglich sizeToFit() aufrufen. Beispielcode:

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

Ich hoffe das hilft!

0
titusmagnus

Eine weitere mögliche Lösung ist das Beenden der Aktualisierung in Ihrem refreshHandler (). so was-

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

Ich habe viel Zeit damit verschwendet, da prefersLargeTitle saga erwartungsgemäß bei einigen Ansichts-Controllern funktioniert und bei einigen das gleiche Problem wie oben erzeugt. 

Die Lösung war für mich die Deaktivierung von Extended Edges Under Top Bars in IB. Für diejenigen Ansichts-Controller, die vorübergehend einen großen Titel anzeigen, bis der Inhalt der Tabellenansicht geladen ist, springt die Navigationsleiste wieder auf normale Größe. Es zeigt nur den großen Titel, wenn Sie die Tabellenansicht nach unten scrollen.

Dies ist abwärtskompatibel mit iOS 10 und lässt keinen leeren Platz über der ersten Zeile in der Tabellenansicht.

Ich hatte prefersLargeTitle auf den Attributen der Navigationscontroller-Attribute nur in IB geprüft - nichts im Code. Gleiches für largeTitleDisplayMode = .always

Warum dies bei einigen View-Controllern geschieht und nicht bei anderen, ich habe absolut keine Ahnung!

0
Ahmed Khedr

Programmatik:

  1. In AppDelegate.Swift:

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()
    
    let navigationController = UINavigationController.init(rootViewController: ViewController())
    window?.rootViewController = navigationController
    
  2. In ViewController:

    überschreibe func viewWillAppear (_ animated: Bool) {super.viewWillAppear (animated)

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

    }

    überschreibe 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)
        ])
    

    }

Stellen Sie sicher, dass Ihre Tabellenansicht zu Ihrer Ansicht hinzugefügt wurde AT ZUERST!

0

Gleiche Ausgabe hier mit Swift 4.2, iOS 12 und überarbeiteten Storyboards. 

Versuchte das Hinzufügen von prefersLargeTitles = true zu viewWillAppear und viewDidLoad, aber mein Problem wurde nicht behoben.

Stattdessen habe ich die überarbeiteten Storyboards wieder in main.storyboard kopiert und die Option gefunden, große Titel in IB zu aktivieren. Stellen Sie diese Option ein und überarbeiten Sie die Storyboards wieder heraus. Jetzt funktioniert alles. Aus irgendeinem Grund hat die anfängliche Umgestaltung die Option gestrichen, und ich konnte sie nicht programmgesteuert aktivieren.

0
Rami