【问题标题】:My navigation bar's large title is too wide. How to fix that?我的导航栏大标题太宽。如何解决?
【发布时间】:2017-11-06 22:04:27
【问题描述】:

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

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

【问题讨论】:

  • 您找到解决方案了吗?

标签: ios swift uinavigationbar navigationcontroller


【解决方案1】:

这是我找到的解决方法

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)
    ]
  }
}

【讨论】:

  • 这很好用!我要做的唯一更改是将最后一行替换为以下内容(提前 Swift 3 语法):if var titleAttributes = navigationController?.navigationBar.largeTitleTextAttributes { titleAttributes[NSFontAttributeName] = UIFont.boldSystemFont(ofSize: fontSize) navigationController?.navigationBar.largeTitleTextAttributes = titleAttributes } 这保留了标题的原始属性,同时仅修改了字体大小。最后.. 可能需要使用guard let title = self.navigationItem.title,具体取决于他们的设置方式。
  • 这应该是公认的答案。不知道为什么另一个是。对 swift 3+ 的代码进行一些调整,效果很好。
  • 我还建议对计算的字体大小与给定的所需最小值进行 max() 比较。对于很长的标题,字体会变得无限小以适应此代码。因此,在将 fontSize 传递给导航栏之前,请执行以下操作以确保最小字体大小永远不会小于 14 磅:让 minFontSize = max(fontSize, 14)。然后,将 minFontSize 传递给导航栏。
  • 太棒了。奇迹般有效。 ?? (Xcode 11.4.1 + iOS 13.3)
【解决方案2】:

你只需要:

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

也可以在 iOS 15 上使用 SwiftUI。

【讨论】:

  • 在 iOS 14 上为我工作。
  • 当我不使用 Swift UI 而是使用带有界面生成器的旧 .xib 时,这非常有用,在 iOS 15.2 上进行了测试。谢谢!
【解决方案3】:

这个问题在这里得到了一些回答: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。希望这会有所帮助。

【讨论】:

  • 它只是在大标题顶部添加标签,所以现在基本上我有两个标题。所以,我必须在两种类型的标题之间做出选择。但它本身是有效的。感谢您的回答。
  • 是的,但在那种情况下我没有大标题的动画
  • 这里一样,这在Large Title上方添加了一个新的单独标题
  • @TigranIskandaryan - 许多阅读这个问题的人都需要一个正常使用大标题的解决方案。它们将向上和向下滚动到足以触发两种类型的标题显示。
【解决方案4】:

已针对 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()的电话

【讨论】:

    【解决方案5】:

    对@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)
        ]
    }
    

    }

    【讨论】:

    • 请解释编辑的具体内容以及它如何改进原始答案。
    猜你喜欢
    • 2018-11-10
    • 2016-06-17
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 2020-03-14
    相关资源
    最近更新 更多