代码之家  ›  专栏  ›  技术社区  ›  alionthego

使用Swift调整UILabel动态内容,使其在宽度和高度上都适合特定框架中的文本

  •  0
  • alionthego  · 技术社区  · 5 年前

    我有一个UILabel,它显示文本以基本填充屏幕。文本可以从一个字母到多个单词。

    private lazy var myLabel: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.baselineAdjustment = .alignCenters
    
        label.numberOfLines = 0
        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.1
    
        let font = UIFont(name: "Arial Rounded MT Bold", size: 400)!
        label.font = font
    
        return label
    }()
    

    其约束如下:

    self.myLabel.translatesAutoresizingMaskIntoConstraints = false
    let leadingConstraint = NSLayoutConstraint(item: self.myLabel, attribute: NSLayoutConstraint.Attribute.leading, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.myLabel.superview, attribute: NSLayoutConstraint.Attribute.leading, multiplier: 1, constant: 20)
    let trailingConstraint = NSLayoutConstraint(item: self.myLabel, attribute: NSLayoutConstraint.Attribute.trailing, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.myLabel.superview, attribute: NSLayoutConstraint.Attribute.trailing, multiplier: 1, constant: -20)
    let topConstraint = NSLayoutConstraint(item: self.myLabel, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.myLabel.superview, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 20)
    let bottomConstraint = NSLayoutConstraint(item: self.myLabel, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.myLabel.superview, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: -20)
    NSLayoutConstraint.activate([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint])
    

    标签的宽度显示正确。它动态调整宽度以匹配内容宽度。然而,在某些情况下,在高度中会有一些剪切。最容易看到的只有一个W字母。它的宽度显示得很好,但高度被剪裁了。

    有什么方法可以让UILabel使用Swift 5调整字体以适应高度和宽度吗?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Michael Montalbano    5 年前

    我总是使用这个,这要归功于backlash-f:

    import Foundation
    import UIKit
    
    class LabelWithAdaptiveTextHeight: UILabel {
    
        override func layoutSubviews() {
            super.layoutSubviews()
            font = fontToFitHeight()
        }
    
        private func fontToFitHeight() -> UIFont {
    
            var minFontSize: CGFloat = 18
            var maxFontSize: CGFloat = 67
            var fontSizeAverage: CGFloat = 0
            var textAndLabelHeightDiff: CGFloat = 0
    
            while (minFontSize <= maxFontSize) {
    
                fontSizeAverage = minFontSize + (maxFontSize - minFontSize) / 2
    
                guard (text?.count)! > 0 else {
                  break
                }
    
                if let labelText: NSString = text as NSString? {
                    let labelHeight = frame.size.height
    
                    let testStringHeight = labelText.size(
                        withAttributes: [NSAttributedString.Key.font: font.withSize(fontSizeAverage)]
                    ).height
    
                    textAndLabelHeightDiff = labelHeight - testStringHeight
    
                    if (fontSizeAverage == minFontSize || fontSizeAverage == maxFontSize) {
                        if (textAndLabelHeightDiff < 0) {
                            return font.withSize(fontSizeAverage - 1)
                        }
                        return font.withSize(fontSizeAverage)
                    }
    
                    if (textAndLabelHeightDiff < 0) {
                        maxFontSize = fontSizeAverage - 1
    
                    } else if (textAndLabelHeightDiff > 0) {
                        minFontSize = fontSizeAverage + 1
    
                    } else {
                        return font.withSize(fontSizeAverage)
                    }
                }
            }
            return font.withSize(fontSizeAverage)
        }
    }