ios Swift - 调整 fontSize 以适应布局的宽度(以编程方式)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28734000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:00:18  来源:igfitidea点击:

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

iosxcodeswiftfonts

提问by MLyck

I've been looking for something to dynamically adjust my fontSizeto fit the width of my layout box. But all the answers I can find, is either to use this:

我一直在寻找一些东西来动态调整我fontSize的布局框的宽度。但我能找到的所有答案都是使用这个:

label.adjustsFontSizeToFitWidth = true

Which does work. But only if I don't have setTranslatesAutoresizingMaskIntoConstraintsset to false.

哪个有效。但前提是我没有setTranslatesAutoresizingMaskIntoConstraints设置为false.

Please note that I don't use storyboards. So to have full control over my other constraints I need this line:

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

label.setTranslatesAutoresizingMaskIntoConstraints(false)

So how can I adjust the font size to fit the width without using storyboard and when I can't use adjustsFontSizeToFitWidth.

那么如何在不使用故事板的情况下调整字体大小以适应宽度,并且当我不能使用adjustsFontSizeToFitWidth.

After I figure out how to adjust the font size to fit the width. I also need to adjust the height of the layout box to fit the font size. There seems to be documentation on that though, but if you happen to know the answer of this as well, it would be greatly appreciated.

在我弄清楚如何调整字体大小以适应宽度之后。我还需要调整布局框的高度以适应字体大小。虽然似乎有关于此的文档,但如果您碰巧也知道这个答案,将不胜感激。

Thanks in advance

提前致谢

回答by Roi Mulia

Try the following commands for your label:

为您的标签尝试以下命令:

label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.2

And try to change the lines of the label to 0 and 1 (check both cases):

并尝试将标签的行更改为 0 和 1(检查两种情况):

label.numberOfLines = 0 // or 1

回答by Vinu David Jose

MinimumScaleFactorrange is 0 to 1. So we are setting the MinimumScaleFactorwith respect to our font size as follows

MinimumScaleFactor范围是 0 到 1。所以我们MinimumScaleFactor按照我们的字体大小设置如下

Objective C

目标 C

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

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

Swift 3.0

斯威夫特 3.0

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

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

回答by SeanRobinson159

I don't know if this will completely answer your question, but you can use this extension to calculate your own font sizes to fit.

我不知道这是否能完全回答你的问题,但你可以使用这个扩展来计算你自己的字体大小。

Swift 3

斯威夫特 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
   }
}

Update - Adds example and updates code to Swift 5

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

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

Here is my logic to make sure that two different labels had the same font size. In my case it was two labels for the user's first and last name. The reason I needed two labels for this, is because each label is independently animated.

这是我确保两个不同标签具有相同字体大小的逻辑。就我而言,它是用户名字和姓氏的两个标签。我为此需要两个标签的原因是每个标签都是独立动画的。

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


}

回答by Roi Mulia

I just did that you needed , Works perfectly ! (Programmatically ONLY) - We are setting large font size to the label , in order to re-scale it to the perfect font size.

我只是做了你需要的,完美的作品!(仅以编程方式) - 我们正在为 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

If you are using AutoLayout, implement this code in viewDidLayoutSubviews(after the layout has been laid out).

如果您使用 AutoLayout,请在viewDidLayoutSubviews(布局布局后)中实现此代码。

Yours, Roi

你的,罗伊

回答by Larry Seyer

Swift 4 conversion of above:

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

Swift 5

斯威夫特 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
    }
}

回答by AthleteInAction

Here's a hack solution:

这是一个黑客解决方案:

var size: CGFloat = 20

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

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

    }