首页 文章

UINavigationBar多行 Headers

提问于
浏览
52

是否有一种直接的方法来覆盖导航控制器中导航栏中当前导航栏项目的titleView?我已经尝试创建一个新的UIView并用我自己的UIVIew替换topView的titleView属性但没有成功 .

基本上,我想要导航栏 Headers 的多行 Headers . 有什么建议?

9 回答

  • 82

    设置 UINavigationItemtitleView 属性 . 例如,在视图控制器的 viewDidLoad 方法中,您可以执行以下操作:

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 480, 44)];
    label.backgroundColor = [UIColor clearColor];
    label.numberOfLines = 2;
    label.font = [UIFont boldSystemFontOfSize: 14.0f];
    label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
    label.textAlignment = UITextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    label.text = @"This is a\nmultiline string";
    
    self.navigationItem.titleView = label;
    
    #if !__has_feature(objc_arc)
    [label release];
    #endif
    

    它显示如下:

    multi-line titlebar label

    请记住,如果 leftBarButtonItem 不是 nil ,则 titleView 属性为ignored .

  • 4

    对于Swift:

    let label = UILabel(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, 44))
    label.backgroundColor = UIColor.clearColor()
    label.numberOfLines = 0
    label.textAlignment = NSTextAlignment.Center
    label.text = "multiline string"
    self.navigationItem.titleView = label
    

    对于swift 4:

    let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0))
        label.backgroundColor = UIColor.clear
        label.numberOfLines = 0
        label.textAlignment = NSTextAlignment.center
        label.text = "first line\nsecond line"
        self.navigationItem.titleView = label
    
  • 3

    Swift解决方案:

    NavigationBar 中的2行:

    private func setupTitleView() {
        let topText = NSLocalizedString("key", comment: "")
        let bottomText = NSLocalizedString("key", comment: "")
    
        let titleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
                               NSFontAttributeName : UIFont.<Font>]
        let subtitleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
                                  NSFontAttributeName : UIFont.<Font>]
    
        let title:NSMutableAttributedString = NSMutableAttributedString(string: topText, attributes: titleParameters)
        let subtitle:NSAttributedString = NSAttributedString(string: bottomText, attributes: subtitleParameters)
    
        title.appendAttributedString(NSAttributedString(string: "\n"))
        title.appendAttributedString(subtitle)
    
        let size = title.size()
    
        let width = size.width
        guard let height = navigationController?.navigationBar.frame.size.height else {return}
    
        let titleLabel = UILabel(frame: CGRectMake(0,0, width, height))
        titleLabel.attributedText = title
        titleLabel.numberOfLines = 0
        titleLabel.textAlignment = .Center
    
        navigationItem.titleView = titleLabel
    }
    

    BarButton 中的2行

    let string = NSLocalizedString("key", comment: "")
        let attributes = [NSForegroundColorAttributeName : UIColor.<Color>,
                          NSFontAttributeName : UIFont.<Font>]
        let size = (string as NSString).sizeWithAttributes(attributes)
        guard let height = navigationController?.navigationBar.frame.size.height else {return}
        let button:UIButton = UIButton(frame: CGRectMake(0, 0, size.width, height))
        button.setAttributedTitle(NSAttributedString(string: string, attributes: attributes), forState: .Normal)
        button.addTarget(self, action: #selector(<SELECTOR>), forControlEvents: .TouchUpInside)
        button.titleLabel?.numberOfLines = 0
        button.titleLabel?.textAlignment = .Right
        let rightBarButton = UIBarButtonItem(customView: button)
        navigationItem.rightBarButtonItem = rightBarButton
    

    结果 -

    enter image description here

  • 3

    经过大量的调整后,我仍然无法在iOS 8中为我工作 . 这是适用于iOS 8/9的可复制粘贴的解决方案 . 积分转到Matt Curtis's github post

    - (void) viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
    
        if(!self.navigationItem.titleView){
            self.navigationItem.titleView = ({
                UILabel *titleView = [UILabel new];
                titleView.numberOfLines = 0;
                titleView.textAlignment = NSTextAlignmentCenter;
                titleView.attributedText = [[NSAttributedString alloc] initWithString:@"2\nLINES" attributes:
                    self.navigationController.navigationBar.titleTextAttributes
                ];
    
                [titleView sizeToFit];
                // You'll need to set your frame otherwise if your line breaks aren't explcit.
    
                titleView;
            });
        }
    }
    
  • 22

    What to do when label is not centered

    如果您遇到与我相同的问题 - 由于后退按钮,该标签不在navigationItem中居中,请将您的UILabel嵌入到UIView中 . 然后UILabel不会被迫增长's text, but stop growing when it'宽度提升视图的宽度 . 有关此问题的更多信息,请访问:Can't set titleView in the center of navigation bar because back button(Darren的回答)

    不居中:

    enter image description here

    - (void)setTwoLineTitle:(NSString *)titleText color:(UIColor *)color font:(UIFont *)font {
        CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2;
    
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
        label.backgroundColor = [UIColor clearColor];
        label.numberOfLines = 2;
        label.font = font;
        label.adjustsFontSizeToFitWidth = YES;
        label.textAlignment = UITextAlignmentCenter;
        label.textColor = color;
        label.text = titleText;
    
        self.navigationItem.titleView = label;
    }
    

    居中:

    enter image description here

    - (void)setTwoLineTitle:(NSString *)titleText color:(UIColor *)color font:(UIFont *)font {
        CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2;
    
        UIView *wrapperView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
    
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
        label.backgroundColor = [UIColor clearColor];
        label.numberOfLines = 2;
        label.font = font;
        label.adjustsFontSizeToFitWidth = YES;
        label.textAlignment = UITextAlignmentCenter;
        label.textColor = color;
        label.text = titleText;
    
        [wrapperView addSubview:label];
    
        self.navigationItem.titleView = wrapperView;
    }
    
  • 1

    这是处理多行 Headers 的 Swift 3 版本:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
        label.backgroundColor = .clear
        label.numberOfLines = 0
        label.textAlignment = .center
        label.font = UIFont.boldSystemFont(ofSize: 14.0)
        label.text = "This is a Multi-Line title of UINavigationBar"
        self.navigationItem.titleView = label
    }
    
  • 6

    这是一种 Swift 4 方式 -

    let upperTitle = NSMutableAttributedString(string: "\(text1)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProDisplay-Heavy", size: 17)!])
    let lowerTitle = NSMutableAttributedString(string: "\n\((text2)!)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProText-Light", size: 11)! , NSAttributedStringKey.foregroundColor: UIColor(hex: "#607D8B")])
    
    upperTitle.append(lowerTitle)
    
    let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height:44))
    label1.numberOfLines = 0
    label1.textAlignment = .center
    label1.attributedText = upperTitle  //assign it to attributedText instead of text
    self.navigationItem.titleView = label1
    
  • 1

    除了来自@gbk的解决方案之外,大多数解决方案都使用硬编码高度44pt作为UIView(包装器视图)和UILabel . 全部都是由代码创建的 . 我忽略了动态读取导航栏高度的@gbk解决方案 .

    在iOS 11(iPhone 5s)上 orientation = landscape 时遇到了问题 . 标签's height won' t进行调整,当我为横向设置一行文本时,文本对齐到导航栏的底部 .

    不知怎的,我发现我可以在故事板中添加UILabel并为此创建一个IBOutlet . 那不是更好吗?

    • 在故事板中添加UIView到导航栏 . 将其拖动到导航栏上时,它将显示为蓝色框 . 如果出现垂直笔划,则将其添加到左/右栏按钮项目数组中 . 注意:只能有一个UIView . 如果正确添加,它将显示在场景面板(左侧)的 Navigation Item 下 .

    • 将UILabel拖入此UIView .
      enter image description here

    • 由于UIView没有SIZE但集中在导航栏中,因此无法添加四个零的约束 . 只需向UILabel添加两个约束,使其位于superview的中心:将中心X和Y对齐到Superview .

    • 像往常一样配置UILabel . 对于多行,我将行数设置为零(0) .

    • 在视图控制器上创建 IBOutlet ,您可以照常使用它 . 要使用不同大小的文本,请使用属性字符串(上面有很多解决方案) .

    我在带有iOS 11.2.6的iPhone 5s上进行了测试,文本位于中心位置没有任何问题,在纵向和横向上工作正常 .

  • 23

    Swift 4

    extension UINavigationItem {
        @objc func setTwoLineTitle(lineOne: String, lineTwo: String) {
            let titleParameters = [NSAttributedStringKey.foregroundColor : UIColor.white,
                                   NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 17)] as [NSAttributedStringKey : Any]
            let subtitleParameters = [NSAttributedStringKey.foregroundColor : UIColor.flatWhite(),
                                      NSAttributedStringKey.font : UIFont.systemFont(ofSize: 12)] as [NSAttributedStringKey : Any]
    
            let title:NSMutableAttributedString = NSMutableAttributedString(string: lineOne, attributes: titleParameters)
            let subtitle:NSAttributedString = NSAttributedString(string: lineTwo, attributes: subtitleParameters)
    
            title.append(NSAttributedString(string: "\n"))
            title.append(subtitle)
    
            let size = title.size()
    
            let width = size.width
            let height = CGFloat(44)
    
            let titleLabel = UILabel(frame: CGRect.init(x: 0, y: 0, width: width, height: height))
            titleLabel.attributedText = title
            titleLabel.numberOfLines = 0
            titleLabel.textAlignment = .center
    
            titleView = titleLabel
        }
    }
    

    Font, color, and navigation bar height are hardcoded here.

相关问题