如何让 NSAttributedString 的下划线样式属性起作用?
How to get NSAttributedString's underline style attribute to work?
使用NSAttributedString
,我想给字符串的一部分加下划线。以下代码未按预期工作:
let string = NSMutableAttributedString(string: "This is my string.")
string.addAttributes([.underlineStyle : NSUnderlineStyle.single],
range: NSRange(location: 5, length: 2))
人们希望 "is" 带有下划线。相反,UITextView 布局引擎会忽略该属性,并在控制台中生成警告。不幸的是,警告没有提到 underlineStyle
或 NSUnderlineStyle
.
这个问题很常见。 Whosebug 上有大量显示正确用法的示例。但是,虽然我确定一定有一些答案可以解释问题,但我阅读的答案仅显示不透明的用法示例。
提出这个问题(下面给出答案)是为了纪念这个问题的解释,以便未来的我和其他人可以从中学习。
NSUnderlineStyle
不是正确的类型
准确地说,但有点无益,documentation 解释说 underlineStyle
属性键采用“NSNumber
包含整数”的属性值。
The value of this attribute is an NSNumber object containing an
integer. This value indicates whether the text is underlined and
corresponds to one of the constants described in NSUnderlineStyle. The
default value for this attribute is styleNone.
许多reader被绘制到NSUnderlineStyle
,点击它,找到类似枚举的样式列表:single
、thick
、patternDash
、double
等。这一切似乎都是一个很好的 Swifty 解决方案。 reader 直觉认为此枚举必须是指定属性值的方式,并键入上面问题中显示的代码类型。
NSUnderlineStyle
的 rawValue
属性 提供了正确的类型
NSUnderlineStyle
不是枚举。它是一个符合 OptionSet
协议的结构体。 OptionSet
协议是一种设置整数位的方便快捷的方法,每个位代表一个二进制状态。 NSUnderlineStyle
结构是该整数的包装器。它的类似枚举的样式实际上是结构上的静态变量,每个 returns 是 NSUnderlineStyle
的一个实例,带有嵌入的整数,只有一个位被翻转以对应于所需的样式。
NSAttributedString
的属性字典几乎可以接受任何东西作为值,因此它很乐意接受 NSUnderlineStyle
的实例。但是使 UITextView
和 UILabel
工作的引擎 TextKit 不知道如何处理 NSUnderlineStyle
实例。当 TextKit 尝试呈现 underlineStyle
属性时,它需要一个整数,以便它可以通过检查整数的位来确定正确的样式。
幸运的是,有一种简单的方法可以获取该整数。 NSUnderlineStyle
的rawValue
属性贩卖它。因此,我们的代码片段的正确工作版本如下:
let string = NSMutableAttributedString(string: "This is my string.")
string.addAttributes([.underlineStyle : NSUnderlineStyle.single.rawValue],
range: NSRange(location: 5, length: 2))
这段代码与题中代码的唯一区别是在"NSUnderlineStyle.single"中增加了“.rawValue”。并且,"is" 带有下划线。
附带说明一下,rawValue
属性 出售的类型是 Int
,而不是 NSNumber
。文档对属性值的引用是 NSNumber
可能会造成混淆。在引擎盖下,为了与 ObjC 互操作,NSAttributedString
将 Int
包装在 NSNumber
中。没有必要(或有利于?)在 NSNumber
.
中显式包装 Int
使用 OptionSet
union
方法组合下划线样式
我们可以将多个下划线样式组合在一起成为一个复合样式。在逐位级别,这是通过对表示两种样式的整数进行逻辑或来实现的。作为 OptionSet
,NSUnderlineStyle
提供了一个 Swifty 替代方案。 NSUnderlineStyle
上的 union(_:)
方法以更通俗易懂的方式实现逻辑或。例如:
NSUnderlineStyle.double.union(.patternDot).rawValue
此代码生成一个 Int
并翻转了适当的位,并且 TextKit 绘制了一个非常漂亮的点状双下划线。当然,并非所有组合都有效。 'NSAttributedString' 可能接受任何东西,但常识和 TextKit
引擎最终会决定。
使用NSAttributedString
,我想给字符串的一部分加下划线。以下代码未按预期工作:
let string = NSMutableAttributedString(string: "This is my string.")
string.addAttributes([.underlineStyle : NSUnderlineStyle.single],
range: NSRange(location: 5, length: 2))
人们希望 "is" 带有下划线。相反,UITextView 布局引擎会忽略该属性,并在控制台中生成警告。不幸的是,警告没有提到 underlineStyle
或 NSUnderlineStyle
.
这个问题很常见。 Whosebug 上有大量显示正确用法的示例。但是,虽然我确定一定有一些答案可以解释问题,但我阅读的答案仅显示不透明的用法示例。
提出这个问题(下面给出答案)是为了纪念这个问题的解释,以便未来的我和其他人可以从中学习。
NSUnderlineStyle
不是正确的类型
准确地说,但有点无益,documentation 解释说 underlineStyle
属性键采用“NSNumber
包含整数”的属性值。
The value of this attribute is an NSNumber object containing an integer. This value indicates whether the text is underlined and corresponds to one of the constants described in NSUnderlineStyle. The default value for this attribute is styleNone.
许多reader被绘制到NSUnderlineStyle
,点击它,找到类似枚举的样式列表:single
、thick
、patternDash
、double
等。这一切似乎都是一个很好的 Swifty 解决方案。 reader 直觉认为此枚举必须是指定属性值的方式,并键入上面问题中显示的代码类型。
NSUnderlineStyle
的 rawValue
属性 提供了正确的类型
NSUnderlineStyle
不是枚举。它是一个符合 OptionSet
协议的结构体。 OptionSet
协议是一种设置整数位的方便快捷的方法,每个位代表一个二进制状态。 NSUnderlineStyle
结构是该整数的包装器。它的类似枚举的样式实际上是结构上的静态变量,每个 returns 是 NSUnderlineStyle
的一个实例,带有嵌入的整数,只有一个位被翻转以对应于所需的样式。
NSAttributedString
的属性字典几乎可以接受任何东西作为值,因此它很乐意接受 NSUnderlineStyle
的实例。但是使 UITextView
和 UILabel
工作的引擎 TextKit 不知道如何处理 NSUnderlineStyle
实例。当 TextKit 尝试呈现 underlineStyle
属性时,它需要一个整数,以便它可以通过检查整数的位来确定正确的样式。
幸运的是,有一种简单的方法可以获取该整数。 NSUnderlineStyle
的rawValue
属性贩卖它。因此,我们的代码片段的正确工作版本如下:
let string = NSMutableAttributedString(string: "This is my string.")
string.addAttributes([.underlineStyle : NSUnderlineStyle.single.rawValue],
range: NSRange(location: 5, length: 2))
这段代码与题中代码的唯一区别是在"NSUnderlineStyle.single"中增加了“.rawValue”。并且,"is" 带有下划线。
附带说明一下,rawValue
属性 出售的类型是 Int
,而不是 NSNumber
。文档对属性值的引用是 NSNumber
可能会造成混淆。在引擎盖下,为了与 ObjC 互操作,NSAttributedString
将 Int
包装在 NSNumber
中。没有必要(或有利于?)在 NSNumber
.
Int
使用 OptionSet
union
方法组合下划线样式
我们可以将多个下划线样式组合在一起成为一个复合样式。在逐位级别,这是通过对表示两种样式的整数进行逻辑或来实现的。作为 OptionSet
,NSUnderlineStyle
提供了一个 Swifty 替代方案。 NSUnderlineStyle
上的 union(_:)
方法以更通俗易懂的方式实现逻辑或。例如:
NSUnderlineStyle.double.union(.patternDot).rawValue
此代码生成一个 Int
并翻转了适当的位,并且 TextKit 绘制了一个非常漂亮的点状双下划线。当然,并非所有组合都有效。 'NSAttributedString' 可能接受任何东西,但常识和 TextKit
引擎最终会决定。