[英]Swift - Adjusting fontSize to fit the width of the layout (programmatically)
I've been looking for something to dynamically adjust my fontSize
to fit the width of my layout box.我一直在寻找一些东西来动态调整我的
fontSize
以适应我的布局框的宽度。 But all the answers I can find, is either to use this:但我能找到的所有答案都是使用这个:
label.adjustsFontSizeToFitWidth = true
Which does work.哪个有效。 But only if I don't have
setTranslatesAutoresizingMaskIntoConstraints
set to false
.但
setTranslatesAutoresizingMaskIntoConstraints
是我没有将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提前致谢
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
MinimumScaleFactor
range is 0 to 1. So we are setting the MinimumScaleFactor
with respect to our font size as follows MinimumScaleFactor
范围是 0 到 1。所以我们将根据字体大小设置MinimumScaleFactor
,如下所示
Objective C目标 C
[lb setMinimumScaleFactor:10.0/[UIFont labelFontSize]];
lb.adjustsFontSizeToFitWidth = YES;
Swift 3.0斯威夫特 3.0
lb.minimumScaleFactor = 10/UIFont.labelFontSize
lb.adjustsFontSizeToFitWidth = true
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)
}
}
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你的,罗伊
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
}
}
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
}
I had a similar problem using a UILabel inside a UITableViewCell and my cell's were adjusting their heights dynamically as well (refer to this if you wanna know more about dynamic cell heights: https://www.raywenderlich.com/129059/self-sizing-table-view-cells ) 我在UITableViewCell中使用UILabel时遇到了类似的问题,我的单元格也在动态调整其高度(如果你想了解更多有关动态单元格高度的信息,请参阅此内容: https : //www.raywenderlich.com/129059/self-sizing -table-view-cells )
And no matter what I did for the mimimum font scale, it wasn't working. 无论我为最小字体量表做了什么,它都无法正常工作。 Turns out, for this feature to work you also have to set the Line Break property to Truncate Tail or Middle or Head.
事实证明,要使此功能起作用,您还必须将Line Break属性设置为Truncate Tail或Middle或Head。 If you have Word Wrap or Character Wrap it won't dynamically scale down your UILabel font (I had a custom font created called: Title 2).
如果你有Word Wrap或Character Wrap,它将不会动态缩小你的UILabel字体(我有一个名为Title 2的自定义字体)。
Hope this helps someone else trying to figure this out. 希望这有助于其他人试图解决这个问题。
Here is a screenshot of my UILabel properties: 这是我的UILabel属性的屏幕截图:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.