这将起作用...
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行。
.byTruncatingTail
,这也是默认值。该解决方案有一个注释,说“或者使用.byWrappingWord”,但那样行不通。请参见https://stackoverflow.com/q/44038022/833197。 - Nicolai Henriksen有趣的问题。这是我的解决方案:
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
}
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)
}
}
}
}
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
sizeToFit()
并不理想,但我想不到其他解决办法。我尝试在循环中使用myLbl.font.withSize(fSize)
,但它无法工作,所以我使用了完整的方法。
希望对你有帮助!
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
}