How do you adjust text kerning using Interface Builder in Xcode 7?

后端 未结 5 1755
無奈伤痛
無奈伤痛 2021-02-13 18:33

There are a myriad of settings for NSAttributedParagraphStyle that I can see in Interface Builder:

相关标签:
5条回答
  • 2021-02-13 18:34

    You can actually do this without the use of a subclass through an extension.

    import UIKit
    
    @IBDesignable
    extension UILabel {
        @IBInspectable
        public var kerning:CGFloat {
            set{
                if let currentAttibutedText = self.attributedText {
                    let attribString = NSMutableAttributedString(attributedString: currentAttibutedText)
                    attribString.addAttributes([NSKernAttributeName:newValue], range:NSMakeRange(0, currentAttibutedText.length))
                    self.attributedText = attribString
                }
            } get {
                var kerning:CGFloat = 0
                if let attributedText = self.attributedText {
                    attributedText.enumerateAttribute(NSKernAttributeName,
                                                      in: NSMakeRange(0, attributedText.length),
                                                      options: .init(rawValue: 0)) { (value, range, stop) in
                                                        kerning = value as? CGFloat ?? 0
                    }
                }
                return kerning
            }
        }
    }
    

    While this won't actually show up in interface builder it will show up and work when you run your app.

    0 讨论(0)
  • 2021-02-13 18:37

    Swift 5

    UILabel Extension:

    @IBDesignable
    extension UILabel {
        @IBInspectable
          var letterSpace: CGFloat {
              set {
                  let attributedString: NSMutableAttributedString!
                  if let currentAttrString = attributedTitle(for: .normal) {
                      attributedString = NSMutableAttributedString(attributedString: currentAttrString)
                  }
                  else {
                      attributedString = NSMutableAttributedString(string: self.titleLabel?.text ?? "")
                      setTitle(.none, for: .normal)
                  }
    
                  attributedString.addAttribute(NSKernAttributeName,
                                                 value: newValue,
                                                 range: NSRange(location: 0, length: attributedString.length))
    
                  setAttributedTitle(attributedString, for: .normal)
              }
    
              get {
                  if let currentLetterSpace = attributedTitle(for: .normal)?.attribute(NSKernAttributeName, at: 0, effectiveRange: .none) as? CGFloat {
                      return currentLetterSpace
                  }
                  else {
                      return 0
                  }
              }
          }
    }
    

    UIButton Extension

        extension UIButton{
              @IBInspectable
              var letterSpace: CGFloat {
                  set {
                      let attributedString: NSMutableAttributedString!
                      if let currentAttrString = attributedTitle(for: .normal) {
                          attributedString = NSMutableAttributedString(attributedString: currentAttrString)
                      }
                      else {
                          attributedString = NSMutableAttributedString(string: self.titleLabel?.text ?? "")
                          setTitle(.none, for: .normal)
                      }
        
                    attributedString.addAttribute(NSAttributedString.Key.kern,
                                                     value: newValue,
                                                     range: NSRange(location: 0, length: attributedString.length))
        
                      setAttributedTitle(attributedString, for: .normal)
                  }
        
                  get {
                    if let currentLetterSpace = attributedTitle(for: .normal)?.attribute(NSAttributedString.Key.kern, at: 0, effectiveRange: .none) as? CGFloat {
                          return currentLetterSpace
                      }
                      else {
                          return 0
                      }
                  }
              }
    }
    
    0 讨论(0)
  • 2021-02-13 18:48

    Swift 4 code:

    @IBDesignable
    extension UILabel {
    @IBInspectable
    public var kerning:CGFloat {
        set{
            if let currentAttibutedText = self.attributedText {
                let attribString = NSMutableAttributedString(attributedString: currentAttibutedText)
                attribString.addAttributes([NSAttributedStringKey.kern:newValue], range:NSMakeRange(0, currentAttibutedText.length))
                self.attributedText = attribString
            }
        } get {
            var kerning:CGFloat = 0
            if let attributedText = self.attributedText {
                attributedText.enumerateAttribute(NSAttributedStringKey.kern,
                                                  in: NSMakeRange(0, attributedText.length),
                                                  options: .init(rawValue: 0)) { (value, range, stop) in
                                                    kerning = value as? CGFloat ?? 0
                }
            }
            return kerning
        }
    }
    }
    
    0 讨论(0)
  • 2021-02-13 18:51

    A shortened attempt:

    @IBDesignable class KerningLabel: UILabel {
    
    
      @IBInspectable var kerning: CGFloat = 0.0 {
        didSet {
          let attrStr = NSMutableAttributedString(string: "Foobar")
          attrStr.addAttributes([NSKernAttributeName: kerning],
                                range: NSMakeRange(0, attrStr.string.characters.count))
          attributedText = attrStr
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-13 19:00

    Create a subclass of UILabel call it KerningLabel have it be comprised of the following code:

    import UIKit
    
    @IBDesignable
    class KerningLabel: UILabel {
    
        @IBInspectable var kerning: CGFloat = 0.0 {
            didSet {
                if attributedText?.length == nil { return }
    
                let attrStr = NSMutableAttributedString(attributedString: attributedText!)
                let range = NSMakeRange(0, attributedText!.length)
                attrStr.addAttributes([NSAttributedStringKey.kern: kerning], range: range)
                attributedText = attrStr
            }
        }
    }
    

    Drag out a label. Change it to your UILabel subclass. Adjust the kerning as desired.

    In obj-c:

    .h

    IB_DESIGNABLE
    @interface KerningLabel : UILabel
    
    @property (nonatomic) IBInspectable CGFloat kerning;
    
    @end
    

    .m

    @implementation KerningLabel
    
    - (void)setKerning:(CGFloat)kerning
    {
        _kerning = kerning;
        if(self.attributedText)
        {
            NSMutableAttributedString *attribString = [[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText];
            [attribString addAttribute:NSKernAttributeName value:@(kerning) range:NSMakeRange(0, self.attributedText.length)];
            self.attributedText = attribString;
        }
    }
    

    @end

    0 讨论(0)
提交回复
热议问题