How to check current font size of UILabel?

后端 未结 3 1744
天涯浪人
天涯浪人 2021-01-25 06:05

I have 3 UILabels and I want to set same (the smallest one from all of 3 possibilities) font for all of them. What is the problem? I don\'t know how to check the cu

3条回答
  •  抹茶落季
    2021-01-25 06:56

    This is one way to get the current size of the UILabel pointsize although I know of more ways if this does not work. This is the cleanest and fastest. See example and extension included.

    import UIKit
    
    class ViewController: UIViewController {
    
        lazy var label1 : UILabel = {
            let lbl = UILabel(frame: CGRect(x: 20, y: 80, width: self.view.bounds.width - 40, height: 40))
            lbl.text = "This is some large text to make it fit to size with a big font size"
            lbl.font = UIFont.systemFont(ofSize: 50, weight: .bold)
            lbl.textColor = .black
            lbl.minimumScaleFactor = 0.01
            lbl.adjustsFontSizeToFitWidth = true
            lbl.numberOfLines = 0
            return lbl
        }()
    
        lazy var label2 : UILabel = {
            let lbl = UILabel(frame: CGRect(x: 20, y: label1.frame.maxY + 5, width: self.view.bounds.width - 40, height: 40))
            lbl.text = "This is one line"
            lbl.font = UIFont.systemFont(ofSize: 20, weight: .bold)
            lbl.textColor = .black
            lbl.minimumScaleFactor = 0.01
            lbl.adjustsFontSizeToFitWidth = true
            lbl.numberOfLines = 0
            return lbl
        }()
    
        lazy var label3 : UILabel = {
            let lbl = UILabel(frame: CGRect(x: 20, y: label2.frame.maxY + 10, width: self.view.bounds.width - 40, height: 80))
            lbl.text = "This is some large text to make it fit to size with a big font size"
            lbl.font = UIFont.systemFont(ofSize: 100, weight: .bold)
            lbl.textColor = .black
            lbl.minimumScaleFactor = 0.01
            lbl.adjustsFontSizeToFitWidth = true
            lbl.numberOfLines = 0
            return lbl
        }()
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            self.view.addSubview(label1)
            self.view.addSubview(label2)
            self.view.addSubview(label3)
    
            var minSize : CGFloat = .greatestFiniteMagnitude
            for sub in self.view.subviews{
                if let lbl = sub as? UILabel{
                    //get the size
                    let font = lbl.adjustedFont()
                    print("the size is \(font.pointSize)")
                    minSize = min(font.pointSize,minSize)
                }
            }
            print("the minimum for all fonts is \(minSize)")
            print("i am going to delay for 3 seconds and then reset all the labels to the minimum size :)")
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3.0) {
                for sub in self.view.subviews{
                    if let lbl = sub as? UILabel{
                        lbl.font = lbl.font.withSize(minSize)
                    }
                }
            }
        }
    }
    extension UILabel{
        func adjustedFont()->UIFont {
            guard let txt = text else {
                return self.font
            }
            let attributes: [NSAttributedString.Key: Any] = [.font: self.font]
            let attributedString = NSAttributedString(string: txt, attributes: attributes)
            let drawingContext = NSStringDrawingContext()
            drawingContext.minimumScaleFactor = self.minimumScaleFactor
            attributedString.boundingRect(with: bounds.size,
                                          options: [.usesLineFragmentOrigin,.usesFontLeading],
                                          context: drawingContext)
    
            let fontSize = font.pointSize * drawingContext.actualScaleFactor
            return font.withSize(CGFloat(floor(Double(fontSize))))
        }
    }
    

    Example in Action

提交回复
热议问题