具有多种颜色的大型导航栏文本

Posted

技术标签:

【中文标题】具有多种颜色的大型导航栏文本【英文标题】:Large Navigation Bar Text With Multiple Colors 【发布时间】:2017-11-13 00:46:29 【问题描述】:

ios 11 在导航栏中引入了更大文本的选项。我想要一个使用多种颜色的标题。例如:

设置标题相当容易,甚至可以更改整个标题的颜色:

[[self navigationItem] setTitle: @"Colors"];
[[[self navigationController] navigationBar] setLargeTitleTextAttributes: @NSForegroundColorAttributeName: [UIColor colorFromHex: redColor]];

我不知道如何只更改部分标题。例如,一种选择像这样的范围的方法 - NSRangeMake(0, 1) - 这样我就可以对其应用颜色。

这应该是可能的吧?

【问题讨论】:

不可能... 这是我的恐惧@Jack,我宁愿避免某种程度的观点探索。 我遇到了同样的问题,试图在 largeTitle 中同时使用粗体和非粗体文本 【参考方案1】:

没有公共 API 可以为大标题设置您自己的属性文本。

解决方案是向下导航视图层次结构。您特别提到您想避免这种情况,但这是修改颜色同时免费获得其余 UINavigationBar 行为的唯一方法。

当然,您始终可以创建自己的UILabel 并设置其attributedText,但您必须自己重新创建任何导航栏动画和其他行为。

老实说,最简单的解决方案是修改您的设计,使其不需要多色大标题,因为目前不支持。


我在“探索”的道路上进行了深入探索,但动画突然恢复到原始文本颜色时存在各种视觉问题。

如果它对任何试图达到类似效果的人有用的话,这是我使用的代码:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    applyColorStyle(toLabels: findTitleLabels())


private func applyColorStyle(toLabels labels: [UILabel]) 
    for titleLabel in labels 
        let attributedString = NSMutableAttributedString(string: titleLabel.text ?? "")
        let fullRange = NSRange(location: 0, length: attributedString.length)
        attributedString.addAttribute(NSAttributedStringKey.font, value: titleLabel.font, range: fullRange)
        let colors = [UIColor.red, UIColor.orange, UIColor.yellow, UIColor.green, UIColor.blue, UIColor.purple]
        for (index, color) in colors.enumerated() 
            attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: NSRange(location: index, length: 1))
        
        titleLabel.attributedText = attributedString
    


private func findTitleLabels() -> [UILabel] 
    guard let navigationController = navigationController else  return [] 
    var labels = [UILabel]()
    for view in navigationController.navigationBar.subviews 
        for subview in view.subviews 
            if let label = subview as? UILabel 
                if label.text == title  labels.append(label) 
            
        
    
    return labels

“探索”方法的缺点是它不是受支持的 API,这意味着它很容易在未来的更新中中断,或者在各种边缘情况下无法按预期工作。

【讨论】:

【参考方案2】:

不幸的是,这不是一件容易的事,它没有得到官方支持。以下是我会考虑的几种方法:

• 覆盖导航栏子类中的 layoutSubiews()。遍历视图层次结构,并弄乱 UILabel 以应用属性。我不建议这样做,我已经不再做类似的事情了——iOS 11 导航栏的行为看似复杂且不可预测。诸如交互式手势之类的东西并不总是适合您添加的任何内容。不过,您的情况比我的情况要简单一些,因此有可能会正常工作。

• 从头开始创建您自己的导航栏样式视图 - 一种不继承自 UINavigationBar 的视图。这是我在做类似事情时最终采取的路线。这需要更多的工作,并且不会反映 Apple 未来对视觉风格所做的更改 - 但另一方面,即使在旧 iOS 版本中,您的应用程序看起来也一样,并且您可以完全控制。

• 隐藏导航栏分隔符,将其恢复为非大尺寸,并在其下方放置您自己的视图以模仿外观(背景是具有 .extraLight 模糊样式的视觉效果视图) - 您可以放置​​自定义在此视图中添加标签。

【讨论】:

以上是关于具有多种颜色的大型导航栏文本的主要内容,如果未能解决你的问题,请参考以下文章

滑动回根视图控制器时,大型导航栏背景颜色变得清晰

如何在 iOS 7 上更改状态栏背景颜色和文本颜色?

更改导航栏文本颜色

iPhone 导航栏标题文本颜色

尝试更改邮件撰写导航栏文本颜色

iOS13状态栏背景颜色与大文本模式下的导航栏不同