How do you adjust text kerning using Interface Bui

2020-06-12 05:04发布

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

But none of these are for text kerning. Is there a way to adjust the text kerning in Xcode 7's Interface Builder for attributed text?

(Please don't answer with how to do this in code - I already know how to do that!)

4条回答
别忘想泡老子
2楼-- · 2020-06-12 05:28

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
        }
    }
}

enter image description here

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

查看更多
神经病院院长
3楼-- · 2020-06-12 05:34

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. enter image description here

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

查看更多
戒情不戒烟
4楼-- · 2020-06-12 05:44

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
    }
  }
}
查看更多
别忘想泡老子
5楼-- · 2020-06-12 05: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
    }
}
}
查看更多
登录 后发表回答