繁体   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