12

I am making an app where I have 3 labels. I am using label auto-shrinking to help adapt the label's font size to the device.

These labels are right next to each other, and that therefore means that I want them to have them the same font size. What currently happens is (because they have different amounts of text) they end up shrinking to different font sizes.

Is there a way to make it so that after scaling, the label with the smallest font size is the standard font for all of the other labels.

Thanks.

D-A UK
  • 1,084
  • 2
  • 11
  • 24
  • could you provide screenshot with marks on it? not clearly understand what to you want to do. – Anton Novoselov Mar 27 '18 at 18:23
  • Possible duplicate of [AutoLayout link two UILabels to have the same font size](https://stackoverflow.com/questions/20262156/autolayout-link-two-uilabels-to-have-the-same-font-size) – Nikaaner Oct 14 '19 at 11:52

2 Answers2

8

Programatically change UIlabel font size after dynamic resizing. See the example below. Calculate current font size with length of string & font. And then get minimum font size and apply separately for each UILabel

override func viewWillAppear(_ animated: Bool) {
    let fontSize1 = self.label1.getFontSizeForLabel()
    let fontSize2 = self.label2.getFontSizeForLabel()
    let fontSize3 = self.label3.getFontSizeForLabel()

    let smallestFontSize = min(min(fontSize1, fontSize2), fontSize3)

    self.label1.font = self.label1.font.withSize(smallestFontSize)
    self.label2.font = self.label2.font.withSize(smallestFontSize)
    self.label3.font = self.label3.font.withSize(smallestFontSize)

    self.label1.adjustsFontSizeToFitWidth = false
    self.label2.adjustsFontSizeToFitWidth = false
    self.label3.adjustsFontSizeToFitWidth = false
}

UILabel Extension

extension UILabel {
    func getFontSizeForLabel() -> CGFloat {
        let text: NSMutableAttributedString = NSMutableAttributedString(attributedString: self.attributedText!)
        text.setAttributes([NSAttributedStringKey.font: self.font], range: NSMakeRange(0, text.length))
        let context: NSStringDrawingContext = NSStringDrawingContext()
        context.minimumScaleFactor = self.minimumScaleFactor
        text.boundingRect(with: self.frame.size, options: NSStringDrawingOptions.usesLineFragmentOrigin, context: context)
        let adjustedFontSize: CGFloat = self.font.pointSize * context.actualScaleFactor
        return adjustedFontSize
    }
}

Storyboard

enter image description here

Output

enter image description here

Britto Thomas
  • 2,092
  • 1
  • 15
  • 28
1
        let labels = mainContainer
            .arrangedSubviews
            .compactMap { $0 as? UILabel }

        let newFontsSize = labels.map { label in
            var fontSize = label.font.pointSize
            
            while label.isTruncated {
                fontSize -= 0.25
                label.font = label.font.withSize(fontSize)
            }

            return fontSize
        }

        if let smallestFontSize = newFontsSize.min() {
            labels.forEach { label in
                label.font = label.font.withSize(smallestFontSize)
            }
        }

And the extension:

extension UILabel {
    var isTruncated: Bool {
        frame.width < intrinsicContentSize.width
    }
}

Mickael Belhassen
  • 2,970
  • 1
  • 25
  • 46