Swift5, iOS 13, UITextField ,placeholdLabel,adjustsFontSizeToFitWidth 实现

784 阅读1分钟

前言:在UITextField 中,有时候placehold 的内容会特别长(例如做多语言的时候,英语&法语会很长),这个时候,需要把内容显示完整,而UI 可能并不会因为这个情况而修改设计图。所以需要取到placeholdLabel,然后把这个laebl 的adjustsFontSizeToFitWidth 设置位true,然后这个方法在(iOS 13,*)上却没有效果,于是我根据placehold文字内容的长度,动态调整fontSize。

extension UITextField {
   
    /// set textField placehold and adjustsFontSizeToFitWidth .  please make sure  you have set this UITextField' s frame
     /// - Parameters:
      ///   - placeholdStr: placehold string
      ///   - textFont: placehold font
      ///   - textColor: placehold color
      ///   - adjustsFontSizeToFitWidth: need adjustsFontSizeToFitWidth
    open func placeholdAttrAndAdjustFontFitWidth(placeholdStr: String,
                                                 textFont: UIFont,
                                                 textColor: UIColor,
                                                 adjustsFontSizeToFitWidth: Bool) {
        placeholdAttrAndAdjustFont(placeholdStr: placeholdStr,
                                   textFont: textFont,
                                   textColor: textColor,
                                   adjustsFontSizeToFitWidth: adjustsFontSizeToFitWidth,
                                   textFieldWid: self.width)
    }
    
    /// set textField placehold' attributeString and adjustsFontSizeToFitWidth .
    /// - Parameters:
    ///   - placeholdStr: placehold string
    ///   - textFont: placehold font
    ///   - textColor: placehold color
    ///   - adjustsFontSizeToFitWidth: need adjustsFontSizeToFitWidth
    ///   - textFieldWid: aim width . If you use snapkit to set self's constraints , you should set this param
    open func placeholdAttrAndAdjustFont(placeholdStr: String,
                                         textFont: UIFont,
                                         textColor: UIColor,
                                         adjustsFontSizeToFitWidth: Bool,
                                         textFieldWid: CGFloat) {
        if #available(iOS 13.0, *) {
            let canUseWid = textFieldWid - 14*2  //left place for border
            guard canUseWid > 0 else {
                return
            }
            let attrStr = NSMutableAttributedString(string: placeholdStr, attributes: [NSAttributedString.Key.font : textFont])
            let needWid = attrStr.getWidth(height: self.height > 0 ? self.height : 12.0) + 14  //Without 14px ,placehold content can't show completly. I want know why too.
            var newFontSize: CGFloat = textFont.pointSize
            if (needWid > canUseWid) && adjustsFontSizeToFitWidth {
                newFontSize = min(textFont.pointSize * (canUseWid/needWid), textFont.pointSize)
            }
            self.attributedPlaceholder = NSAttributedString(string: placeholdStr, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: newFontSize), NSAttributedString.Key.foregroundColor : textColor])
        }else {
            self.attributedPlaceholder = NSAttributedString(string: placeholdStr, attributes: [NSAttributedString.Key.font : textFont, NSAttributedString.Key.foregroundColor : textColor])
            guard let lab = self.value(forKey: "placeholderLabel") as? UILabel else {
                return
            }
            lab.adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth
        }
    }
} 

使用方式, 在viewDidLoad 中 调用

 func testAttrStr() {
        let textF = UITextField(frame: CGRect(x: 100, y: 250, width: 100, height: 60))
        view.addSubview(textF)
        textF.backgroundColor = .green
        textF.placeholdAttrAndAdjustFontFitWidth(
        placeholdStr: "123456789888", textFont: textF.font!, 
        textColor: .blue, 
        adjustsFontSizeToFitWidth: true)
    }