iOS 11 - UINavigationItem titleView when using Large Titles mode

前端 未结 2 1039
陌清茗
陌清茗 2021-02-04 13:00

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 navigatio

相关标签:
2条回答
  • 2021-02-04 13:38

    I can't find any documentation on this, so I played a bit. It seems in iOS 11, you won't be able to get that title to be a button and display large at the left.

    I don't know if this is a bug or the expected result, as it seems to be a new feature. The latest (iOS 11) Human Interface Guidelines (HIG) discuss the larger title label as being a way to give the user clear context. The HIG also discuss space between buttons. However, there's no discussion of using a button as the title.


    To recreate, I set up a Single View project. I embedded the view controller in a navigation controller.

    In ViewController.swift's viewDidLoad, I added this code:

        let titleButton = UIButton(type: .roundedRect)
        titleButton.setTitle("Hello Button!", for: UIControlState.normal)
    
        let navController = parent as! UINavigationController
    
        navController.navigationBar.topItem!.title = "Hello???"
        navController.navigationBar.topItem!.titleView = titleButton
        navController.navigationBar.prefersLargeTitles = true
    

    This ends up looking something like your example.

    IF I:

    • set .title to empty string, or remark the line out: navbar is stretched, and no title text shows (or title text set in Interface Builder shows)

    • remark out .prefersLargeTitles, or set it to false: the navbar is the normal height, the button displays, but no title text displays.

    • remark out the titleView line, AND:

      • leave the .prefersLargeTitles set to true: the title text displays large at the left, and the navbar's height is stretched.
      • set the .prefersLargeTitles to false: the title text displays in the top center, and the navbar is normal height.

    Update: link to sample project on GitHub

    0 讨论(0)
  • 2021-02-04 13:48

    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.

    0 讨论(0)
提交回复
热议问题