iOS14 navigationItem.largeTitleDisplayMode = .always not work

At last solved the issue.

Edge case:

If you're using large title, and you have multiple scroll views on the same view controller. Navigation bar will listen to scroll actions on the subviews (immediate subview) of kind UIScrollView.

Solution

You have to prevent current view controller's large title collapsing feature.

Its same concept as @BaQiWL mentioned. But not just adding view.addSubview(UIView()) will solve this issue, if you're using storyboard.

To do this you have to add view as Viewcontroller's first subview. (view.sendSubviewToBack does the trick).

// Call this method on `viewDidLoad`
private func preventLargeTitleCollapsing() {
    let dummyView = UIView()
    view.addSubview(dummyView)
    view.sendSubviewToBack(dummyView)
}

OR via Storyboard:

enter image description here


My ViewController has a UIPageViewController, UIPageViewController has a UIScrollView, this is the key point.

This link explains and solves the problem

add view.addSubview(UIView()) in ViewController's viewDidLoad


For iOS 14, need to add sizeToFit function. Below code always work.

navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.sizeToFit()

If the scene is based on a UITableView, you need to scroll it.

override func viewDidLoad() {
    super.viewDidLoad()
    
    // enough for the first scene.
    navigationController?.navigationBar.prefersLargeTitles = true
    tableView.setContentOffset(CGPoint(x: 0, y: -1), animated: false) // hack for modal prefersLargeTitles
    
}

always present largeTitleDisplayMode for modal view controller