Swift 3 - 调整字体大小以适应宽度,多行显示

12
我有一个UILabel,它的字体大小为42.0 pt,并且标签的宽度是根据除标签本身之外的因素(即标签左右两侧的内容)使用自动约束设置的。 我想自动调整字体大小以适应标签的宽度,但是也希望在需要时将其拆分成两行。类似于这样:

enter image description here

我知道你可以调整字体大小以适应标签的宽度,但仅在将行数设置为1时才能这样做。那我该如何实现呢?

1
如果将行数设置为0会发生什么? - brandonscript
1
文本仍然保持在一行上,字体大小不会缩小。 - Chris Schlitt
5个回答

4

这将起作用...

  • 设置您的标签的最小比例因子,如图所示。
  • adjustsFontSizeToFitWidth设置为true
  • 设置行数=2 //如果您想要更多的行,则为零(0)
  • 将断行模式设置为'.byTruncatingTail'以获得2行

Swift 5
对于动态文本信息,请将行数设置为零,这对于变化的文本非常有用。

var label = UILabel()
let stringValue = "A label\nwith\nmultiline text."
label.text = stringValue
label.numberOfLines = 2 // 0
label.lineBreakMode = .byTruncatingTail // or .byWrappingWord
label.minimumScaleFactor = 0.5 // It is not required but nice to have a minimum scale factor to fit text into label frame
label.adjustsFontSizeToFitWidth = true //needed in Swift 5

在此输入图像描述

此外,不要将标签的高度约束设置为超过2行。


4
当将numberOfLines设置为1以外的值时,尝试使用此方法,但字体大小不会自动缩小。 - Chris Schlitt
请分享你尝试过的代码,我已经测试过了,对于你的示例非常有效。 - Krunal
重要的是使用.byTruncatingTail,这也是默认值。该解决方案有一个注释,说“或者使用.byWrappingWord”,但那样行不通。请参见https://stackoverflow.com/q/44038022/833197。 - Nicolai Henriksen

2

有趣的问题。这是我的解决方案:

let labelText = self.mylabel.text //where mylabel is the label
let labelSeperated = self.labelText.components(seperatedBy: " ")
if labelSeperated.count > 1 {
    myLabel.lineBreakMode = .byWordWrapping
    myLabel.numberOfLines = 0 
} else {
    myLabel.numberOfLines = 1
    myLabel.adjustsFontSizeToFitWidth = true 
}

将此代码放在需要更改标签的位置。如果有两个或更多数字,则将行号设置为0,否则仅设置为1行。
如果您想调整多行标签的大小,请查看此博客文章:这里

这个解决方案唯一的问题是,当有多行文本时,字体大小不会改变。 - Chris Schlitt
@ChrisSchlitt 你看过博客文章了吗? - Papershine

1

Swift 5

extension UILabel{
func adjustsFontSizeToFit(maxFontSize:CGFloat,width:CGFloat,height:CGFloat) {
    self.numberOfLines = 0
    var fontSize:CGFloat = maxFontSize
    if self.sizeThatFits(CGSize(width: width, height: .infinity)).height > height{
        while self.sizeThatFits(CGSize(width: width, height: .infinity)).height > height{
            fontSize -= 1
            self.font = self.font.withSize(fontSize)
        }
    }
}

}


1
Swift 5
func setFontForLabel(label:UILabel, maxFontSize:CGFloat, minFontSize:CGFloat, maxLines:Int) {

    var numLines: Int = 1
    var textSize: CGSize = CGSize.zero
    var frameSize: CGSize = CGSize.zero
    let font: UIFont = label.font.withSize(maxFontSize)

    frameSize = label.frame.size

    textSize = (label.text! as NSString).size(withAttributes: [NSAttributedString.Key.font: font])

    // Determine number of lines
    while ((textSize.width/CGFloat(numLines)) / (textSize.height * CGFloat(numLines)) > frameSize.width / frameSize.height) && numLines < maxLines {
        numLines += 1
    }

    label.font = font
    label.adjustsFontSizeToFitWidth = true
    label.numberOfLines = numLines
    label.minimumScaleFactor = minFontSize/maxFontSize
}

Swift 3

我看了paper111发布的文章,不幸的是它是用Obj-C编写的,并且sizeWithFont: ,constrainedToSize: , lineBreakMode: 方法已被弃用。(- -;)

他的回答很好,但仍然没有提供固定的大小。我的做法是从一个UILabel开始,它除了高度之外几乎都有(这对大多数人来说可能是相同的)。

let myFrame = CGRect(x: 0, y:0, width: 200, height: self.view.height)
let myLbl = UILabel(frame: myFrame)
let finalHeight:CGFloat = 300

myLbl.font = UIFont(name: "Chalkduster", size: 16.0)
myLbl.lineBreakMode = .byWordWrapping
myLbl.numberOfLines = 0
myLbl.text = "Imagine your long line of text here"
addSubview(myLbl)
myLbl.sizeToFit()

guard myLbl.frame.height > finalHeight else { return }
var fSize:CGFloat = 16 //start with the default font size
    repeat {
        fSize -= 2
        myLbl.font = UIFont(name: "Chalkduster", size: fSize)
        myLbl.sizeToFit()
    } while myLbl.frame.height > finalHeight

你可以看到,如果不需要调整大小,就会有一个“guard”阻止调整。此外,多次调用sizeToFit()并不理想,但我想不到其他解决办法。我尝试在循环中使用myLbl.font.withSize(fSize),但它无法工作,所以我使用了完整的方法。

希望对你有帮助!


0
@Krunal的答案对我有帮助,但在有未知行数的情况下不起作用,所以这是我想出的解决方案。您还可以设置最大和最小字体大小。希望能帮到其他人!
Swift 2.2 - 抱歉,我还没有迁移到Swift 3。
func setFontForLabel(label:UILabel, maxFontSize:CGFloat, minFontSize:CGFloat, maxLines:Int) {

    var numLines: Int = 1
    var textSize: CGSize = CGSizeZero
    var frameSize: CGSize = CGSizeZero
    var font: UIFont = UIFont.systemFontOfSize(maxFontSize)

    frameSize = label.frame.size

    textSize = (label.text! as NSString).sizeWithAttributes([NSFontAttributeName: font])

    // Determine number of lines
    while ((textSize.width/CGFloat(numLines)) / (textSize.height * CGFloat(numLines)) > frameSize.width / frameSize.height) && numLines < maxLines {
        numLines += 1
    }

    label.font = font
    label.adjustsFontSizeToFitWidth = true
    label.numberOfLines = numLines
    label.minimumScaleFactor = minFontSize/maxFontSize
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接