Gian
Gian

Reputation: 220

iOS 11 prefersLargeTitles not displaying until scroll

I'm having issues with iOS 11's large titles when using a Table View Controller.

I have set prefersLargeTitles to true in the viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    navigationController?.navigationBar.prefersLargeTitles = true
}

When running my app the title appears as if prefersLargeTitles is set to small, but if I then scroll down, the large title appears.

I have 2 UIViewControllers, and they both display the large title correctly, bar the UITableViewController.

I have tried different combinations of setting prefersLargeTitles to true in the code and within the storyboard, where you can set Large Title to Automatic, Always or Never.

I can only find one other question on Stack Overflow which refers to this exact issue, but none of the answers seem to solve it.

Has anyone else who has run into this issue been able to solve it?

Upvotes: 4

Views: 3219

Answers (3)

Matthew Wakefield
Matthew Wakefield

Reputation: 31

Perhaps you are reloading the tableView prior to viewDidLoad? I observed the same behavior today. In my case, I had a didSet on a variable that was set before viewDidLoad that called tableView.reloadData.

I was able to fix this by adding a guard so the reloadData only happened when the variable wasn't previously nil, meaning the first time.

Here's my calling class for reference...

/// Master Controller in UISplitViewController
class MyMasterViewController: UIViewController {

  private let controller = MyTableViewController()

  override func viewDidLoad() {
    super.viewDidLoad()

    controller.instanceVariable = data
    showDetailViewController(navigationController, sender: self)
  }

...

  private func reloadDetail() {
    controller.instanceVariable = newData
  }
}

And here's the fix - added the guard statement below...

/// Detail Controller in UISplitViewController
class MyTableViewController: UITableViewController {

  var instanceVariable: MyData! {
    didSet {
      guard oldValue != nil else { return }
      tableView.reloadData()
    }
  }

  // UITableViewController Methods...
}

Hope this helps! If my example doesn't make sense, I'd suggest commenting out all references to tableView.reloadData and then only re-adding when sure they aren't getting called until after the tableView loads initially.

Upvotes: 2

Gandalf458
Gandalf458

Reputation: 2269

After setting prefersLargeTitles, you can trigger the large titles to show by calling setContentOffset on your UITableView.

override func viewDidLoad() {
    super.viewDidLoad()

    navigationController?.navigationBar.prefersLargeTitles = true
    self.tableView.setContentOffset(CGPoint(x: 0, y: -1), animated: true)
}

Upvotes: 5

Fred Truter
Fred Truter

Reputation: 666

You need to enable large titles on the navigation controller. It is tricky to find, so please see the screenshot below. enter image description here

If your table view controller seques on to other detail view controllers then you should set large title to Never in the storyboard for those other view controllers.

DO NOT MESS with prefersLargeTitles in code like this:

      self.navigationController?.navigationBar.prefersLargeTitles = false

Upvotes: 1

Related Questions