多种颜色的大导航栏文本

Axe*_*eva 8 uinavigationbar nsattributedstring uinavigationitem ios

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

在此输入图像描述

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

[[self navigationItem] setTitle: @"Colors"];
[[[self navigationController] navigationBar] setLargeTitleTextAttributes: @{NSForegroundColorAttributeName: [UIColor colorFromHex: redColor]}];
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚的是如何改变标题的一部分.例如,一种选择这样的范围的方法 - NSRangeMake(0, 1)- 以便我可以为它应用颜色.

这一定是可能的,对吧?

nat*_*ter 4

没有公共 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
}
Run Code Online (Sandbox Code Playgroud)

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