Search code examples
iosnavigationbarios11uinavigationitemtitleview

iOS 11 - UINavigationItem titleView when using Large Titles mode


I'm trying to understand either it's a bug or it's the expected behavior.

On iOS 10 and earlier we could set up a custom title, using navigationItem.titleView.
On iOS 11, when setting our navigationItem.largeTitleDisplayMode = .always and setting navigationItem.titleView = <Some cool UIButton> it's displaying both the normal navigation title bar and the large navigation title.

Illustration: enter image description here

To sum up:

How can we use custom titleView on our Large Navigation Title?

EDIT : This is the expected result:

enter image description here


Solution

  • I was able to replace the navigation bar big title with a custom view by using a subclass of UINavigationBar and manually changing the view hierarchy :

    @interface MYNavigationBar : UINavigationBar
    
    @end
    
    @implementation MYNavigationBar
    
    // ...
    
    - (void)layoutIfNeeded
    {
        [self setupTitle];
        [super layoutIfNeeded];
    }
    
    - (void)setupTitle
    {
        // UINavigationBar
        // -> ...
        // -> _UINavigationBarLargeTitleView
        //   -> UILabel << Big Title Label
        //   -> UIView
        //     -> UILabel << Big Title Label animating from back button during transitions
    
        for (UIView *view in self.subviews) {
            NSString *className = NSStringFromClass(view.classForCoder);
            if ([className containsString:@"LargeTitleView"]) {
                for (UIView *view2 in view.subviews) {
                    if ([view2 isKindOfClass:[UILabel class]]) {
                        [self convertLabel:(UILabel *)view2];
                    }
                    for (UIView *view3 in view2.subviews) {
                        if ([view3 isKindOfClass:[UILabel class]]) {
                            [self convertLabel:(UILabel *)view3];
                        }
                    }
                }
            }
        }
    }
    
    - (void)convertLabel:(UILabel*)label
    {
        // I kept the original label in the hierarchy (with the background color as text color)
        // and added my custom view as a subview. 
        // This allow the transformations applied to the original label to be also applied to mine.
    }
    

    Please note that Apple might reject your app because of this trick.