Change character spacing on UILabel within Interface Builder

前端 未结 13 2558
说谎
说谎 2020-12-23 09:21

Is there anyway to change the character spacing (track) on UILabel text using Interface Builder? If not, is there a way to do it programmatically on an existing UILabel that

相关标签:
13条回答
  • 2020-12-23 09:43

    Ended up using this for now to get existing attributed text and modify to add character spacing:

    let attributedString = discoveryTitle.attributedText as NSMutableAttributedString
    attributedString.addAttribute(NSKernAttributeName, value: 1.0, range: NSMakeRange(0, attributedString.length))
    discoveryTitle.attributedText = attributedString
    

    Swift 3:

    let attributedString = NSMutableAttributedString(string: discoveryTitle.text)
    attributedString.addAttribute(NSKernAttributeName, value: CGFloat(1.0), range: NSRange(location: 0, length: attributedString.length))
    discoveryTitle.attributedText = attributedString
    

    Using NSRange instead of NSMakeRange works in Swift 3.

    0 讨论(0)
  • 2020-12-23 09:44

    SWIFT 4 UILabel extension:

    import UIKit
    
    extension UILabel {
    
        @IBInspectable
        var letterSpace: CGFloat {
            set {
                let attributedString: NSMutableAttributedString!
                if let currentAttrString = attributedText {
                    attributedString = NSMutableAttributedString(attributedString: currentAttrString)
                } else {
                    attributedString = NSMutableAttributedString(string: text ?? "")
                    text = nil
                } 
                attributedString.addAttribute(NSAttributedString.Key.kern,
                                              value: newValue,
                                              range: NSRange(location: 0, length: attributedString.length))
                attributedText = attributedString
            }
    
            get {
                if let currentLetterSpace = attributedText?.attribute(NSAttributedString.Key.kern, at: 0, effectiveRange: .none) as? CGFloat {
                    return currentLetterSpace
                } else {
                    return 0
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-23 09:48

    Swift 5.3.1

    extension UILabel {
      func addCharacterSpacing(kernValue: Double = 1.15) {
        if let labelText = text, labelText.count > 0 {
          let attributedString = NSMutableAttributedString(string: labelText)
            attributedString.addAttribute(NSAttributedString.Key.kern, value: kernValue, range: NSRange(location: 0, length: attributedString.length - 1))
          attributedText = attributedString
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-23 09:49

    Here is a solution for Swift 4 that won't override existing text attributes:

    extension UILabel {
    
        /**
         Add kerning to a UILabel's existing `attributedText`
         - note: If `UILabel.attributedText` has not been set, the `UILabel.text`
         value will be returned from `attributedText` by default
         - note: This method must be called each time `UILabel.text` or
         `UILabel.attributedText` has been set
         - parameter kernValue: The value of the kerning to add
         */
        func addKern(_ kernValue: CGFloat) {
            guard let attributedText = attributedText,
                attributedText.string.count > 0,
                let fullRange = attributedText.string.range(of: attributedText.string) else {
                    return
            }
            let updatedText = NSMutableAttributedString(attributedString: attributedText)
            updatedText.addAttributes([
                .kern: kernValue
                ], range: NSRange(fullRange, in: attributedText.string))
            self.attributedText = updatedText
        }
    }
    
    0 讨论(0)
  • 2020-12-23 09:51

    Try this. It will add the character spacing you assign, either you set simple text or attributed text.

    open class UHBCustomLabel : UILabel {
        @IBInspectable open var characterSpacing:CGFloat = 1 {
            didSet {
                updateWithSpacing()
            }
    
        }
    
        open override var text: String? {
            set {
                super.text = newValue
                updateWithSpacing()
            }
            get {
                return super.text
            }
        }
        open override var attributedText: NSAttributedString? {
            set {
                super.attributedText = newValue
                updateWithSpacing()     
            }
            get {
                return super.attributedText
            }
        }
        func updateWithSpacing() {
            let attributedString = self.attributedText == nil ? NSMutableAttributedString(string: self.text ?? "") : NSMutableAttributedString(attributedString: attributedText!)
            attributedString.addAttribute(NSKernAttributeName, value: self.characterSpacing, range: NSRange(location: 0, length: attributedString.length))
            super.attributedText = attributedString
        }
    }
    
    0 讨论(0)
  • 2020-12-23 09:54

    Programming approach. (Try this, it should work for you)
    Note: I tested in Swift 4

    let label = UILabel()
    let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
    let attrString = NSMutableAttributedString(string: stringValue)
    var style = NSMutableParagraphStyle()
    style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
    style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
    
    // Line spacing attribute
    attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
    
    // Character spacing attribute
    attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))
    
    label.attributedText = attrString
    
    0 讨论(0)
提交回复
热议问题