簡體   English   中英

確定具有最大寬度的多行UILabel的最大字體大小

[英]Determining the maximum font size for a multi-line UILabel with maximum width

現在,我知道有數十個問題問同樣的問題,但是大多數問題與多行標簽無關,或者答案不起作用或已過時。 我看了

我試圖找出以顯示所需的最小字體大小message 3線的UILabel內占用僅maximumContentWidth寬度並用字體UIFont.systemFont(.regular) 現在,我意識到UILabel中有一些屬性可以使它自動縮小以適合它,但對我不起作用。 我需要確定最小字體大小的特定數字,以便將其應用於多個其他UILabel,其中一些顯示的文字明顯更少。

我的最大字體大小為20,最小字體大小為13。

我目前正在部分使用這里找到的解決方案但是它僅在理論上有效。 我不確定為什么,但是當我在“ fa fa fa ...”這樣的字符串上做了一些很棒的測試文本時,重復fa直到我從視覺上知道一個fa不能容納最大字體。 但是,對於“ Ww wwwwwwwww wwww wwww www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www www wwwwwww www wwwwwwwwwwwwwww。” 系統會完全崩潰,無法使文本變小到所需的大小。

這是探測器

extension UILabel {

    var isTruncated: Bool {

        guard let labelText = text else {
            return false
        }

        let labelTextSize = (labelText as NSString).boundingRect(
            with: CGSize(width: frame.size.width, height: .greatestFiniteMagnitude),
            options: .usesLineFragmentOrigin,
            attributes: [.font: font],
            context: nil).size

        return labelTextSize.height > bounds.size.height
    }
}

這是我的使用方式:

    var testLabel = UILabel()
    var font = 20
    testLabel.numberOfLines = 3
    testLabel.frame.size.width = maximumContentWidth
    while font > 13 {
        testLabel.text = message
        testLabel.font = UIFont.systemFont(ofSize: font, weight: .regular)
        testLabel.sizeToFit()
        if !testLabel.isTruncated {
            break
        }
        font -= 0.1
    }

為什么這種方法不起作用,什么是合適的替代方法?

如果我的代碼正確,則您正在嘗試減小字體大小,直到它適合UILabel大小為止。 因此,字體的大小將盡可能大。

主要問題在於您的while循環中。 在每個步驟上,您都需要設置新font並調用sizeToFit這會使您更改標簽框架以適合字體大小。 之后,您的isTruncated將返回false

您需要在每個步驟上手動設置UILabel的框架,而不是調用sizeToFit()

testLabel.numberOfLines = 3
testLabel.text = message

while font > 13 {
    testLabel.font = UIFont.systemFont(ofSize: font, weight: .regular)
    testLabel.frame.size = CGSize(width: maximumContentWidth,
                                  height: maximumContentHeight)
    if !testLabel.isTruncated {
        break
    }
    font -= 0.1
}

之后,您將設置所需的標簽大小,並檢查新的字體大小是否使文本適合它。

UPDATE

我沒有提到您要確保UILabel不超過3行。 這有點棘手,因為沒有簡單或簡單的方法來知道UILabel有多少行。 但這就是我在項目中使用的解決方案

extension UILabel {
    func getLinesCount() -> Int {
        let text = self.text ?? ""
        let rectWidth = self.frame.width

        let myFont = CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil)
        let attStr = NSMutableAttributedString(string: text)
        let range = NSRange(location: 0, length: attStr.length)
        attStr.addAttribute(kCTFontAttributeName as NSAttributedStringKey, value: myFont, range: range)

        let frameSetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString)
        let path: CGMutablePath = CGMutablePath()
        let rect = CGRect(x: 0, y: 0, width: rectWidth, height: CGFloat.greatestFiniteMagnitude)
        path.addRect(rect, transform: .identity)

        let frame: CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
        guard let lines = CTFrameGetLines(frame) as? [Any] else { return 0 }
        return lines.count
    }
}

此方法根據標簽的fontwidth ,為您的標簽返回多行。 您可以在while循環中使用它來檢查它如何變化。

希望對您有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM