LineHeight на UILabel не центрированный контент Swift - PullRequest
0 голосов
/ 09 июля 2020

Я создал пользовательский UILabel, чтобы установить lineHeight, определенный Figma (стороннее приложение, например Sketch), значение lineHeightMultiple равно 1,28. Но визуально метка не центрирована по вертикали:

Мой собственный класс UILabel:

open class CustomLabel: UILabel {
    open var alignment: NSTextAlignment = .left
    open var lineHeight: CGFloat = 1.28

    override open var text: String? {
        didSet {
            setLineSpacing(lineHeightMultiple: lineHeight, textAlingment: alignment)
            layoutIfNeeded()
        }
    }

    public override var intrinsicContentSize: CGSize {
        let labelSize = sizeThatFits(CGSize(width: frame.width, height: .greatestFiniteMagnitude))

        var desiredWidth: CGFloat = 0.0

        let computedWidth = labelSize.width
        desiredWidth = computedWidth

        let size = CGSize(width: desiredWidth, height: labelSize.height)
        return size
    }

    open override func drawText(in rect: CGRect) {
        switch contentMode {
        case .top:
            let height = sizeThatFits(rect.size).height
            if let stringText = text {
                let stringTextAsNSString = stringText as NSString
                let labelStringSize = stringTextAsNSString.boundingRect(with: CGSize(width: self.frame.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil).size
                super.drawText(in: CGRect(x: 0, y: 0, width: self.frame.width, height: height))
            } else {
                super.drawText(in: rect)
            }
        case .bottom:
            var newRect = rect
            let height = sizeThatFits(rect.size).height
            newRect.origin.y += rect.size.height - height
            newRect.size.height = height
            super.drawText(in: newRect)
        default:
            super.drawText(in: rect)
        }
    }

    public override func awakeFromNib() {
        super.awakeFromNib()
        setup()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    private func setup() {
        textColor = .black
        
        adjustsFontForContentSizeCategory = true
        translatesAutoresizingMaskIntoConstraints = false
        numberOfLines = 0
        lineBreakMode = .byClipping
        contentMode = .center
        baselineAdjustment = .alignCenters
        sizeToFit()
    }
}

И расширение, которое я использую для установки lineHeightMultiple:

func setLineSpacing(lineHeightMultiple: CGFloat = 0.0, textAlingment: NSTextAlignment = .left) {

    guard let labelText = self.text else {
        return
    }

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 1.0
    paragraphStyle.lineHeightMultiple = lineHeightMultiple
    paragraphStyle.lineBreakMode = .byTruncatingTail
    paragraphStyle.alignment = textAlingment
    
    let attributedString: NSMutableAttributedString
    if let labelattributedText = self.attributedText {
        attributedString = NSMutableAttributedString(attributedString: labelattributedText)
    } else {
        attributedString = NSMutableAttributedString(string: labelText)
    }
    //swiftlint:disable legacy_constructor
    attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedString.length))
    //swiftlint:enable legacy_constructor
    self.attributedText = attributedString
}

Проблема в том, что текст не центрирован по горизонтали, не знаю почему, это работает, только если я поставлю lineHeightMultiple на 1.0.

введите описание изображения здесь

...