简体   繁体   中英

Adjust UILabel dynamic content to fit text in a particular frame both in width and height using Swift

I have a UILabel which displays text to basically fill the screen. The text can be from one letter up to many words.

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

it's constraints as such:

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

The label displays correctly in width. It adjusts width dynamically to match the content width. However in Height there is some clipping in certain cases. The easiest to see is just one W letter. It displays fine in width but is clipped in height.

Is there any way to have a UILabel adjust the font to fit both height and width using Swift 5?

I always use this thanks to backslash-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)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM