iOS 11 Large Navigation Bar Title Unexpected Velocity

iOS 11 large navigation bar title unexpected velocity

I have been debugging this for a couple days, and I have found a workaround.

First, What Was Going On?

It is the UIScrollView that is not performing well with the largeTitle. Since there is scrolling up on the scroll view at the same time as the navigation bar becoming smaller, there exists twice the scrolling compared to the actual scroll.

I confirmed this by intentionally setting:

scrollView.contentOffset.y = scrollView.contentOffset.y * 0.5

This indeed made it move as desired. But, this couldn't solve the problem entire problem because it did not yield a smooth transition while going from large navigation bar to small navigation bar. You can try the below code out.

if scrollView.contentOffset.y > 0 {
if self.navigationController!.navigationBar.frame.size.height > 44.0 {
scrollView.contentOffset.y = scrollView.contentOffset.y * 0.5
}
}

This worked 'okay' when scrolled slowly, but when you fling downward, it acts slow at first (while navigation height is large), and then speeds up afterwards.

WORKAROUND

Simply put, you CANNOT use UIScrollView with the iOS 11 large navigation bar. You ought to use UITableViewController instead.

Since my view is composed of multiple horizontal UICollectionViews spread along vertically, I used UITableView with different sections to form the UI using storyboard.
If you use UITableViewController, it performs as desired.

AppStore and all other Apple-made native apps must do it this way.

iOS 11 large title navigation bar snaps instead of smooth transition

I faced same issue - I had UIViewController embedded in UINavigationController, the UIViewController had tableview with leading, trailing, top, bottom constraints to safe area. The whole tableview behaved jumpy / snappy. The trick was to change top constraint of tableview to superview.

iOS 11 large-title navigation bar not collapsing

Good news! I've just figured out that if I set "Large Titles" to "Never" on the storyboard, and then set it via code, then it works:

- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;
}

Seems like Apple forgot to handle the case when the navigation item has its largeTitleDisplayMode set via the Interface Builder.

So until they fix this issue, leave "Large Titles" as "Never" on storyboards, and set them via code in viewDidLoad.

You just need to do that to the first view controller. Subsequent view controllers honor the value in storyboard.

iOS 11 Large Title change event

I have added this observer in my UIViewController's subclass's ViewWillAppear. and setting the color according to its height as below:

In ViewWillAppear:

UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];

In viewWillDisappear:

UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar removeObserver:self forKeyPath:@"frame" context:NULL];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"frame"]) {
[self setNavigationBarColour];;
}

}

- (void)setNavigationBarColour
{
UINavigationBar *navBar = self.navigationController.navigationBar;
CGFloat height = navBar.bounds.size.height;
if(height>44)
{
[navBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[navBar setTranslucent:YES];
[navBar setShadowImage:[UIImage new]];
}
else
{
[navBar setBackgroundImage:[[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault];
[navBar setTranslucent:NO];
[navBar setShadowImage:[[UINavigationBar appearance] shadowImage]];
}
}

How to set large title on navigation bar for iOS 11?

Here is code snippet to display large title on left side of navigation bar for iOS 11 or later.

Objective C:

  self.title = @"Your title";
if (@available(iOS 11, *)) {
self.navigationController.navigationBar.prefersLargeTitles = true;
self.navigationController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
}

Swift:

       self.title = "Your title"
if #available(iOS 11, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationItem.largeTitleDisplayMode = .always
}

You need to put check condition for iOS 11 before building application.

Requirement to test large title:

  • Xcode 9.0,
  • Mac OSX - 10.12.6 or later,
  • iPhone/iPad or Xcode 9 simulator with iOS 11.

Use the increased navigation-bar title in iOS 11

The only change done to UINavigationBar API for iOS 11 is prefersLargeTitles.

Documentation here: https://developer.apple.com/documentation/uikit/uinavigationbar/

You can do it to your own apps with one small change: check "Prefers Large Titles" for your navigation bar in IB, or if you prefer to do it in code using:

navigationController?.navigationBar.prefersLargeTitles = true

If you need to change the text attributes of the large title you need to use the new largeTitleTextAttributes property on UINavigationBar:

UINavigationBar.appearance().largeTitleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.black
]


Related Topics



Leave a reply



Submit