Is there a Swift method for indenting the large title of a navigation bar in line with cellLayoutMarginsFollowReadableWidth?

Viewed 674

Currently, on iPad, my UINavigationBar large title looks strange because it does not indent to where my UITableView cells are. This is because my table view and cells follow readable width. Is there a way of indenting this title or is the only piece of advice to align the cells with the title (make them not follow readable width). I would really appreciate anyone who took the time to respond.

2 Answers

When you first load your view controller, you should retrieve the minX coordinate of the current readableContentGuide and set that value to the left layoutMargin value. As so:

let leftMargin = self.view.readableContentGuide.layoutFrame.minX    
self.navigationController?.navigationBar.layoutMargins.left = leftMargin

Then, you'll also want to make sure your layout adjusts dynamically so that if the user rotates their screen (or on an iPad, is using a variable window size) the title will remain aligned:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    coordinator.animate(alongsideTransition: { _ in
        let leftMargin = view.readableContentGuide.layoutFrame.minX    
        navigationController?.navigationBar.layoutMargins.left = leftMargin
    }, completion: nil)
}

The answer of @swillsea did not work correctly for me: on rotation of the device the left margin of the large title seems to have a wrong initial position during the rotation animation. One can see this in the simulator with the options for slow animations enabled.

The reason for this is that the screen is laid out in the new dimension using the old left margin. During the rotation animation the margin is animated into the correct final size.

Instead of updating the left margin when the size changes I simply update as part of the normal layout chain:

override func viewWillLayoutSubviews() {
    let leftMargin = self.view.readableContentGuide.layoutFrame.minX
    self.navigationController?.navigationBar.layoutMargins.left = leftMargin
}

The effect for me is now, that the left margin of the title is now equal to that of my readable content in all phases of the rotation animation.

Related