簡體   English   中英

Swift - 調整 fontSize 以適應布局的寬度(以編程方式)

[英]Swift - Adjusting fontSize to fit the width of the layout (programmatically)

我一直在尋找一些東西來動態調整我的fontSize以適應我的布局框的寬度。 但我能找到的所有答案都是使用這個:

label.adjustsFontSizeToFitWidth = true

哪個有效。 setTranslatesAutoresizingMaskIntoConstraints是我沒有將setTranslatesAutoresizingMaskIntoConstraints設置為false

請注意,我不使用故事板。 所以要完全控制我的其他約束,我需要這一行:

label.setTranslatesAutoresizingMaskIntoConstraints(false)

那么如何在不使用故事板的情況下調整字體大小以適應寬度以及何時無法使用adjustsFontSizeToFitWidth

在我弄清楚如何調整字體大小以適應寬度之后。 我還需要調整布局框的高度以適應字體大小。 雖然似乎有關於此的文檔,但如果您碰巧也知道這個答案,將不勝感激。

提前致謝

為您的標簽嘗試以下命令:

label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.2

並嘗試將標簽的行更改為 0 和 1(檢查兩種情況):

label.numberOfLines = 0 // or 1

MinimumScaleFactor范圍是 0 到 1。所以我們將根據字體大小設置MinimumScaleFactor ,如下所示

目標 C

[lb setMinimumScaleFactor:10.0/[UIFont labelFontSize]];
lb.adjustsFontSizeToFitWidth = YES;

斯威夫特 3.0

lb.minimumScaleFactor = 10/UIFont.labelFontSize
lb.adjustsFontSizeToFitWidth = true

我不知道這是否能完全回答你的問題,但你可以使用這個擴展來計算你自己的字體大小。

斯威夫特 3

extension String {
   func height(constrainedBy width: CGFloat, with font: UIFont) -> CGFloat {
       let constraintSize = CGSize(width: width, height: .max)
       let boundingBox = self.boundingRectWithSize(constraintSize, options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

       return boundingBox.height
   }

   func width(constrainedBy height: CGFloat, with font: UIFont) -> CGFloat {
       let constrainedSize = CGSize(width: .max, height: height)
       let boundingBox = self.boundingRectWithSize(constrainedSize, options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

       return boundingBox.width
   }
}

更新 - 向 Swift 5 添加示例和更新代碼

斯威夫特 5

extension String {
    func height(constrainedBy width: CGFloat, with font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

        return boundingBox.height
    }

    func width(constrainedBy height: CGFloat, with font: UIFont) -> CGFloat {
        let constrainedRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constrainedRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

        return boundingBox.width
    }
}

這是我確保兩個不同標簽具有相同字體大小的邏輯。 就我而言,它是用戶名字和姓氏的兩個標簽。 我為此需要兩個標簽的原因是每個標簽都是獨立動畫的。

class ViewController: UIViewController {
      ...

      func viewDidLoad() {
         super.viewDidLoad()
         fixFontSizes()
         ...
      }

      func fixFontSizes() {
         let leadingMargin = self.leadingContainerConstraint.constant
         let trailingMargin = self.trailingContainerConstraint.constant
         let maxLabelWidth = self.view.bounds.width - leadingMargin - trailingMargin

         let firstName = self.firstNameLabel.text ?? ""
         let lastName = self.lastNameLabel.text ?? ""

         let firstNameWidth = firstName.width(constrainedBy: self.container.bounds.height, with: self.firstNameLabel.font)
         let lastNameWidth = lastName.width(constrainedBy: self.container.bounds.height, with: self.lastNameLabel.font)

         let largestLabelWidth = max(firstNameWidth, lastNameWidth)
         guard largestLabelWidth > maxLabelWidth else { return }

         let largestTextSize = max(self.firstNameLabel.font.pointSize, self.lastNameLabel.font.pointSize)

         let labelToScreenWidthRatio = largestLabelWidth / maxLabelWidth
         let calculatedMaxTextSize = floor(largestTextSize / labelToScreenWidthRatio)

         self.firstNameLabel.font = self.firstNameLabel.font.withSize(calculatedMaxTextSize)
         self.lastNameLabel.font = self.lastNameLabel.font.withSize(calculatedMaxTextSize)
      }


}

我只是做了你需要的,完美的作品! (僅以編程方式) - 我們正在為 label 設置大字體大小,以便將其重新縮放到完美的字體大小。

self.label.font = UIFont(name: "Heiti TC", size: 60)
self.label.numberOfLines = 0
self.label.minimumScaleFactor = 0.1
self.label.baselineAdjustment = .alignCenters
self.label.textAlignment  = .center

如果您使用 AutoLayout,請在viewDidLayoutSubviews實現此代碼(在布局布局之后)。

你的,羅伊

Swift 4 以上的轉換:

extension String
{
    func height(constrainedBy width: CGFloat, with font: UIFont) -> CGFloat
    {
        let constraintSize = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintSize, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

        return boundingBox.height
    }

    func width(constrainedBy height: CGFloat, with font: UIFont) -> CGFloat
    {
        let constrainedSize = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constrainedSize, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

        return boundingBox.width
    }
}

斯威夫特 5

extension String
{
    func height(constrainedBy width: CGFloat, with font: UIFont) -> CGFloat
    {
        let constraintSize = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintSize, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)

        return boundingBox.height
    }

    func width(constrainedBy height: CGFloat, with font: UIFont) -> CGFloat
    {
        let constrainedSize = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constrainedSize, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)

        return boundingBox.width
    }
}

這是一個黑客解決方案:

var size: CGFloat = 20

    while titleLabel.frame.width > containerView.frame.width {

        titleLabel.font = UIFont.systemFont(ofSize: size)
        titleLabel.sizeToFit()
        size -= 1

    }

我在UITableViewCell中使用UILabel時遇到了類似的問題,我的單元格也在動態調整其高度(如果你想了解更多有關動態單元格高度的信息,請參閱此內容: https//www.raywenderlich.com/129059/self-sizing -table-view-cells

無論我為最小字體量表做了什么,它都無法正常工作。 事實證明,要使此功能起作用,您還必須將Line Break屬性設置為Truncate Tail或Middle或Head。 如果你有Word Wrap或Character Wrap,它將不會動態縮小你的UILabel字體(我有一個名為Title 2的自定義字體)。

希望這有助於其他人試圖解決這個問題。

這是我的UILabel屬性的屏幕截圖:

在此輸入圖像描述

暫無
暫無

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

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