iOS 8 - 在Interface Builder中更改UILabel上的字符间距

cod*_*man 45 interface-builder uilabel ios swift

无论如何使用Interface Builder更改UILabel文本上的字符间距(轨道)?如果没有,有没有办法在已经使用属性文本创建的现有UILabel上以编程方式执行此操作?

bud*_*ino 85

我知道它不是Interface Builder解决方案,但您可以创建UILabel扩展,然后为UILabel您想要的任何内容添加间距:

extension UILabel {
  func addCharacterSpacing(kernValue: Double = 1.15) {
    if let labelText = text, labelText.count > 0 {
      let attributedString = NSMutableAttributedString(string: labelText)
      attributedString.addAttribute(NSAttributedStringKey.kern, value: kernValue, range: NSRange(location: 0, length: attributedString.length - 1))
      attributedText = attributedString
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

考虑更改默认kernValue1.15的东西,能与您的设计更好.


实现时总是在设置文本值后添加字符间距:

myLabel.text = "We used to be so close"
myLabel.addCharacterSpacing()
Run Code Online (Sandbox Code Playgroud)

如果您计划在应用程序的不同位置使用不同的间距,则可以覆盖默认的kern值:

myLabelWithSpecialNeeds.addCharacterSpacing(kernValue: 1.3)
Run Code Online (Sandbox Code Playgroud)

  • 非常好的答案!一点补充:您可以将 if 子句更改为 `if let textString = text, textString.length > 0` 以 **catch index out of bounds** 当字符串为 "" (空) 时。 (2认同)

cod*_*man 38

现在结束使用它来获取现有的属性文本并修改以添加字符间距:

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

斯威夫特3:

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

在Swift 3中使用NSRange而不是NSMakeRange.

  • +1.很棒的答案.如果你的文本必须保持居中,则将字距调整应用于除最后一个字符之外的所有字符,即将`NSMakeRange(0,attributedString.length)`更改为`NSMakeRange(0,attributedString.length - 1)`.[来源](http://stackoverflow.com/a/23743928/1305067) (4认同)

luk*_*302 25

对于完全静态的文本,如视图的标题或特别是launchScreen,您可以插入占用极小宽度的字母(例如'l'字符)0 opacity.或者将其颜色设置为与背景相同.

我知道这个事实,这不是最漂亮的解决方案,但它是唯一能够在不编写任何代码的情况下工作的解决方案 - 直到您可以通过在Xcode中指定属性来实现.

结果 如何

编辑/附加想法:为了使您的间距更加可变,您可以更改填充字符之间的字体大小.(感谢@ mohamede1945的想法)

  • 嗨陆 - 我真的爱你,但这确实是一个坏主意.我很抱歉! (4认同)
  • @ mohamede1945好主意,在我真正读你评论并再次阅读我的答案之前(给了我一段时间)我也有想法也许改变字体大小 - 然后阅读你的评论...如果两个人独立想出同样的想法,它必须是好的;) (3认同)
  • 以本地化为例......它会搞砸它 (2认同)
  • 这对于可访问性来说是一个非常糟糕的主意。如果您使用它,请确保将可访问性标签设置为真实文本。 (2认同)

Mik*_*hov 16

Swift 3.2和界面构建器

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(NSKernAttributeName,
                                           value: newValue,
                                           range: NSRange(location: 0, length: attributedString.length))

            attributedText = attributedString
        }

        get {
            if let currentLetterSpace = attributedText?.attribute(NSKernAttributeName, at: 0, effectiveRange: .none) as? CGFloat {
                return currentLetterSpace
            }
            else {
                return 0
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 它完美地工作。似乎我在我的代码中遗漏了一部分。对不起 (2认同)

Bes*_*rov 9

试试这个!!

创建CustomLabel类

@interface CustomLabel : UILabel
@property (assign, nonatomic) CGFloat myLineSpacing;
@end


@implementation CustomLabel

- (void)setMyLineSpacing:(CGFloat)myLineSpacing {
    _myLineSpacing = myLineSpacing;
    self.text = self.text;
}

- (void)setText:(NSString *)text {
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = _myLineSpacing;
    paragraphStyle.alignment = self.textAlignment;
    NSDictionary *attributes = @{NSParagraphStyleAttributeName: paragraphStyle};
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text
                                                                         attributes:attributes];
    self.attributedText = attributedText;
}
Run Code Online (Sandbox Code Playgroud)

并设置运行时属性

在此输入图像描述

请注意,这实际上是行间距(也称为前导 ...在过去的日子里(前数字)你要在线之间放置铅(金属)以增加线之间的间隙.对于字母之间的间距,这称为字距调整.这里是如何做字距调整/sf/answers/1479880951/


Ada*_*aka 7

为什么你们所有人都在定义NSMUTABLEAttributedString.您不必明确设置范围.它使emojis有时看起来很奇怪.这是我的解决方案,在Swift 4中测试过.

extension UILabel {
    func addCharactersSpacing(_ value: CGFloat = 1.15) {
        if let textString = text {
            let attrs: [NSAttributedStringKey : Any] = [.kern: value]
            attributedText = NSAttributedString(string: textString, attributes: attrs)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Mac*_*wia 6

SWIFT 4 UILabel 扩展:

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Fre*_*one 5

受budidinho的回答启发,这是一个更灵活的解决方案,适用于您希望更改具有不同线间距的标签的间距.无需进入函数并更改值,您只需将其作为参数传递即可.

extension UILabel {
  func setTextSpacingBy(value: Double) {
    if let textString = self.text {
      let attributedString = NSMutableAttributedString(string: textString)
      attributedString.addAttribute(NSKernAttributeName, value: value, range: NSRange(location: 0, length: attributedString.length - 1))
      attributedText = attributedString
    }
  }
}
Run Code Online (Sandbox Code Playgroud)