在 Xcode 7 中如何使用 Interface Builder 调整文本字距?
How do you adjust text kerning using Interface Builder in Xcode 7?
我可以在 Interface Builder 中看到 NSAttributedParagraphStyle
的无数设置:
但其中 none 用于文本字距微调。有没有办法在 Xcode 7 的 Interface Builder 中为属性文本调整文本字距?
(请不要在代码中回答如何做到这一点 - 我已经知道如何做到这一点!)
创建一个 UILabel 的子类,称为 KerningLabel,由以下代码组成:
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
}
}
}
拖出一个标签。将其更改为您的 UILabel 子类。根据需要调整字距。
在 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
您实际上可以通过扩展在不使用子类的情况下做到这一点。
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
}
}
}
虽然这实际上不会显示在界面生成器中,但它会在您 运行 您的应用程序时显示并工作。
缩短的尝试:
@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
}
}
}
Swift 4 码:
@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
}
}
}
Swift 5
UILabel 扩展:
@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 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
}
}
}
}
我可以在 Interface Builder 中看到 NSAttributedParagraphStyle
的无数设置:
但其中 none 用于文本字距微调。有没有办法在 Xcode 7 的 Interface Builder 中为属性文本调整文本字距?
(请不要在代码中回答如何做到这一点 - 我已经知道如何做到这一点!)
创建一个 UILabel 的子类,称为 KerningLabel,由以下代码组成:
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
}
}
}
拖出一个标签。将其更改为您的 UILabel 子类。根据需要调整字距。
在 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
您实际上可以通过扩展在不使用子类的情况下做到这一点。
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
}
}
}
虽然这实际上不会显示在界面生成器中,但它会在您 运行 您的应用程序时显示并工作。
缩短的尝试:
@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
}
}
}
Swift 4 码:
@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
}
}
}
Swift 5
UILabel 扩展:
@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 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
}
}
}
}