我的导航栏的大标题太宽了。如何解决?

My navigation bar's large title is too wide. How to fix that?

我正在使用导航控制器,我已经将其导航栏的 prefersLargeTitle 属性 设置为 true。一切正常,但是当我的标题文本变得太大时,它不适合 space。外观如下:

是否可以通过某种方式使标题(当导航栏的 prefersLargeTitle 属性 设置为 true 时)动态调整其字体大小,如果是这样,如何实现?

这个问题在这里得到了一些回答:How to resize Title in a navigation bar dynamically

self.title = "Your TiTle Text"
let tlabel = UILabel(frame: CGRectMake(0, 0, 200, 40))
tlabel.text = self.title
tlabel.textColor = UIColor.whiteColor()
tlabel.font = UIFont(name: "Helvetica-Bold", size: 30.0)
tlabel.backgroundColor = UIColor.clearColor()
tlabel.adjustsFontSizeToFitWidth = true
self.navigationItem.titleView = tlabel

也就是说,这略有不同,因为您设置了 prefersLargeTitle 属性。 现在,我不确定 tlabel.adjustsFontSizeToFitWidth = true 是否覆盖了 prefersLargeTitle 属性,但请尝试一下,看看它是否有效。这里还有一些关于导航项目大标题的附加信息:https://developer.apple.com/documentation/uikit/uinavigationitem/2909056-largetitledisplaymode。希望这有帮助。

这是我找到的解决方法

override func viewDidLoad() {
  super.viewDidLoad()

  title = yourTitle
  adjustLargeTitleSize()
}

extension UIViewController {
  func adjustLargeTitleSize() {
    guard let title = title, #available(iOS 11.0, *) else { return }

    let maxWidth = UIScreen.main.bounds.size.width - 60
    var fontSize = UIFont.preferredFont(forTextStyle: .largeTitle).pointSize
    var width = title.size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: fontSize)]).width

    while width > maxWidth {
      fontSize -= 1
      width = title.size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: fontSize)]).width
    }

    navigationController?.navigationBar.largeTitleTextAttributes =
        [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: fontSize)
    ]
  }
}

对@vicente.fava 的回答进行了编辑 - 效果很好。

self.title = longTitle
self.navigationController?.navigationBar.prefersLargeTitles = true
adjustLargeTitleSize()


extension UIViewController {
func adjustLargeTitleSize() {
    guard let title = title, #available(iOS 11.0, *) else { return }

    let maxWidth = UIScreen.main.bounds.size.width - 60
    var fontSize = UIFont.preferredFont(forTextStyle: .largeTitle).pointSize
    var width = title.size(withAttributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize)]).width

    while width > maxWidth {
        fontSize -= 1
        width = title.size(withAttributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize)]).width
    }

    navigationController?.navigationBar.largeTitleTextAttributes =
        [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: fontSize)
    ]
}

}

已测试 iOS12 ~ iOS14

extension UINavigationController {

    func adjustFontSize(with title: String) {
        let insetToEdge: CGFloat = 16
        let maxWidth = navigationBar.bounds.width - insetToEdge - insetToEdge
        let largeTitleFont = UIFont.preferredFont(forTextStyle: .largeTitle)
        var fontSize = largeTitleFont.pointSize

        var largeTitleTextAttributes: [NSAttributedString.Key: Any] = [:]

        var largeTitleSize: CGSize
        if #available(iOS 13.0, *) {
            largeTitleSize = NSAttributedString(
                string: title,
                attributes: navigationBar.standardAppearance.largeTitleTextAttributes)
                .size()
        } else {
            largeTitleTextAttributes = [NSAttributedString.Key.font: largeTitleFont]
            largeTitleSize = NSAttributedString(
                string: title,
                attributes: largeTitleTextAttributes)
                .size()
        }
        guard largeTitleSize.width > maxWidth else { return }
        while largeTitleSize.width > maxWidth {
            fontSize -= 1
            if #available(iOS 13.0, *) {
                largeTitleTextAttributes = navigationBar.standardAppearance.largeTitleTextAttributes
            }
            largeTitleTextAttributes[NSAttributedString.Key.font] = UIFont.BO.font(
                ofSize: fontSize,
                weight: .semiBold)
            largeTitleSize = NSAttributedString(
                string: title,
                attributes: largeTitleTextAttributes)
                .size()
        }
        if #available(iOS 13.0, *) {
            navigationBar.standardAppearance.largeTitleTextAttributes = largeTitleTextAttributes
        } else {
            navigationBar.largeTitleTextAttributes = largeTitleTextAttributes
        }
    }

}

来自viewDidLoad()

的来电

您只需要:

UILabel.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).adjustsFontSizeToFitWidth = true

还在 iOS 15.

上使用 SwiftUI