有没有办法在Interface Builder上更改UILabel文本的字符间距(跟踪)?如果不行,是否有办法在已经创建带属性文本的UILabel上编程更改字符间距(跟踪)?
有没有办法在Interface Builder上更改UILabel文本的字符间距(跟踪)?如果不行,是否有办法在已经创建带属性文本的UILabel上编程更改字符间距(跟踪)?
我知道这不是Interface Builder的解决方案,但您可以创建一个UILabel
扩展程序,然后向任何您想要的UILabel
添加间距:
extension UILabel {
func addCharacterSpacing(kernValue: Double = 1.15) {
guard let text = text, !text.isEmpty else { return }
let string = NSMutableAttributedString(string: text)
string.addAttribute(NSAttributedString.Key.kern, value: kernValue, range: NSRange(location: 0, length: string.length - 1))
attributedText = string
}
}
kernValue
从1.15
更改为适合您设计的值。
myLabel.text = "We used to be so close"
myLabel.addCharacterSpacing()
myLabelWithSpecialNeeds.addCharacterSpacing(kernValue: 1.3)
这个解决方案将覆盖您在UILabel
的attributedText
上可能拥有的任何其他属性。
if let textString = text, textString.length > 0
,以便在字符串为空时捕获索引越界。 - inf1783我现在先使用这个方法来获取现有的属性文本并进行修改,以添加字符间距:
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
在Swift 3中,使用NSRange代替NSMakeRange可以正常工作。
NSMakeRange(0, attributedString.length)
更改为NSMakeRange(0, attributedString.length - 1)
。来源 - paulvsmax(0, attributedString.length - 1)
即可帮助解决问题。 - nahung89对于完全静态的文本,比如视图的标题或特别是启动屏幕,您可以插入占用极少宽度(例如“l”字符)并具有0不透明度
的字母。或者将其颜色设置为与背景相同。
我知道这并不是最美观的解决方案,但除了在Xcode中指定属性之前,这是唯一不需要编写任何代码并且有效的解决方案。
编辑/其他想法:要使间隔更加变化,您可以更改填充字符的字体大小。(感谢@mohamede1945提出的想法)
Swift 3.2 和 Interface Builder
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
}
}
}
}
Swift 5及更高版本
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
}
}
}
请尝试这个!!
创建自定义标签类
@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;
}
并设置运行时属性
注意:这实际上是行距(也称为前导)。在很久以前(数字化之前),你会在行之间放置铅(金属)来增加行之间的间隔。对于字母间距,那被称为字距调整。这里是如何进行字距调整的https://dev59.com/yWEi5IYBdhLWcg3wltEl#21141156
为什么大家都在定义NSMUTABLEAttributedString。其实你不必显式地设置范围,这有时会使表情看起来很奇怪。 这是我的解决方案,在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)
}
}
}
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
}
}
}
}
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
}
}
import UIKit
extension UILabel {
func addCharacterSpacing(_ kernValue: Double = 1.30) {
guard let attributedString: NSMutableAttributedString = {
if let text = self.text, !text.isEmpty {
return NSMutableAttributedString(string: text)
} else if let attributedText = self.attributedText {
return NSMutableAttributedString(attributedString: attributedText)
}
return nil
}() else { return}
attributedString.addAttribute(
NSAttributedString.Key.kern,
value: kernValue,
range: NSRange(location: 0, length: attributedString.length)
)
self.attributedText = attributedString
}
}