05. Changing an Attributed Strin
NSMutableAttributedString
declares a number of methods for changing both characters and attributes. You must take care not to modify attribute values after they have been passed to an attributed string. You may also need to repair inconsistencies that can be introduced if you modify an attributed string.
- NSMutableAttributedString声明了许多用于更改字符和属性的方法。 将属性值传递给属性字符串后,必须注意不要修改它们。 如果修改属性字符串,则可能还需要修复可能引入的不一致性。
Modifying Attributes
- 修改属性
NSMutableAttributedString
declares a number of methods for changing both characters and attributes, such as the primitive replaceCharactersInRange:withString:
and setAttributes:range:
, or the more convenient methods addAttribute:value:range:
, applyFontTraits:range:
, and so on.
- NSMutableAttributedString声明了许多用于更改字符和属性的方法,例如基本replaceCharactersInRange:withString:和setAttributes:range:,或更方便的方法addAttribute:value:range:,applyFontTraits:range:等等。
The following example illustrates how to specify a link attribute for a selected range in an attributed string, underline the text, and color it blue. Note that you can define whatever value you want for the link attribute, it is up to you to interpret the value when the link is selected—see Accessing Attributes—typically, however, you use either a string or a URL. For an explanation of the role of beginEditing
and endEditing
(shown in the sample), see Fixing Inconsistencies.
- 以下示例说明如何为属性字符串中的选定范围指定链接属性,为文本加下划线并将其着色为蓝色。 请注意,您可以为链接属性定义所需的任何值,您可以在选择链接时解释该值 - 请参阅访问属性 - 但是,通常使用字符串或URL。 有关beginEditing和endEditing的作用的说明(如示例所示),请参阅修复不一致。
NSMutableAttributedString *string; // assume string exists
NSRange selectedRange; // assume this is set
NSURL *linkURL = [NSURL URLWithString:@"http://www.apple.com/"];
[string beginEditing];
[string addAttribute:NSLinkAttributeName
value:linkURL
range:selectedRange];
[string addAttribute:NSForegroundColorAttributeName
value:[NSColor blueColor]
range:selectedRange];
[string addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSSingleUnderlineStyle]
range:selectedRange];
[string endEditing];
Attribute values assigned to an attributed string become the property of that string, and should not be modified “behind the attributed string” by other objects. Doing so can render inconsistent the attributed string’s internal state. There are two main reasons for this:
分配给属性字符串的属性值将成为该字符串的属性,不应被其他对象“隐藏在属性字符串后面”。 这样做会导致属性字符串的内部状态不一致。 这有两个主要原因:
-
How an attribute value propagates through an attributed string is not predictable. If you change the value, you might be editing more of the attributed string than you thought. In fact the value could have been copied to the undo stack, or to a totally different document, and so on.
- 属性值如何通过属性字符串传播是不可预测的。 如果更改该值,您可能正在编辑比您想象的更多的属性字符串。 实际上,该值可能已复制到撤消堆栈,或者复制到完全不同的文档,依此类推。
-
Attributed strings do caching and uniquing of attributes, which assumes attribute values do not change. The assumption is that
isEqual:
andhash
on attribute values will not change once the attribute value has been set.- 归因字符串执行缓存和取消属性,这假设属性值不会更改。 假设是isEqual:并且一旦设置了属性值,hashon属性值就不会改变。
If you must change attribute values, and are sure that the change will apply to the correct range, there are two strategies you can adopt:
如果必须更改属性值,并确保更改将应用于正确的范围,则可以采用两种策略:
-
Use an attribute value whose
isEqual:
andhash
do not depend on the values you are modifying.- 使用isEqual:和hash不依赖于您正在修改的值的属性值。
-
Use indirection: use the attribute value as a lookup key into a table where the actual value can be changed. For instance, this might be the appropriate approach for having a “stylesheet”-like attribute.
- 使用间接:将属性值用作查找键,进入可以更改实际值的表。 例如,这可能是具有“样式表”类属性的适当方法。
Fixing Inconsistencies
- 修复不一致问题
All of the methods for changing a mutable attributed string properly update the mapping between characters and attributes, but after a change some inconsistencies can develop. Here are some examples of attribute consistency requirements:
所有用于更改可变属性字符串的方法都会正确地更新字符和属性之间的映射,但在更改之后,可能会出现一些不一致的情况。 以下是属性一致性要求的一些示例:
-
Paragraph styles must apply to entire paragraphs.
- 段落样式必须适用于整个段落。
-
Scripts may only be assigned fonts that support them. For example, Kanji and Arabic characters can’t be assigned the Times-Roman font, and must be reassigned fonts that support these scripts.
- 只能为脚本分配支持它们的字体。 例如,汉字和阿拉伯字符不能分配Times-Roman字体,并且必须是支持这些脚本的重新分配字体。
-
Deleting attachment characters from the string requires the corresponding attachment objects to be released. Similarly, removing attachment objects requires the corresponding attachment characters to be removed from the string.
- 从字符串中删除附件字符需要释放相应的附件对象。 同样,删除附件对象需要从字符串中删除相应的附件字符。
-
A code editing application that displays all language keywords in boldface can automatically assign this attribute as the user changes the font or edits the text.
- 以粗体显示所有语言关键字的代码编辑应用程序可以在用户更改字体或编辑文本时自动分配此属性。
The Application Kit’s extensions to NSMutableAttributedString
define methods to fix these inconsistencies as changes are made. This allows the attributes to be cleaned up at a low level, hiding potential problems from higher levels and providing for very clean update of display as attributes change. There are four methods for fixing attributes and two to group editing changes:
Application Kit对NSMutableAttributedString的扩展定义了在进行更改时修复这些不一致的方法。 这允许在较低级别清理属性,从较高级别隐藏潜在问题,并在属性改变时提供非常干净的显示更新。 有四种方法可以修复属性,两种方法可以对编辑更改进行分组:
-
fixAttributesInRange:
-
fixAttachmentAttributeInRange:
-
fixFontAttributeInRange:
-
fixParagraphStyleAttributeInRange:
-
beginEditing
-
endEditing
The first method, fixAttributesInRange:
, invokes the other three fix...
methods to clean up deleted attachment references, font attributes, and paragraph attributes, respectively. The individual method descriptions explain what cleanup entails for each case.
- 第一个方法fixAttributesInRange:分别调用其他三个fix ...方法来清除已删除的附件引用,字体属性和段落属性。 各个方法描述解释了每种情况需要清理的内容。
NSMutableAttributedString
provides beginEditing
and endEditing
methods for subclasses of NSMutableAttributedString
to override. These methods allow instances of a subclass to record or buffer groups of changes and clean themselves up on receiving an endEditing
message. The endEditing
method also allows the receiver to notify any observers that it has been changed. NSTextStorage
’s implementation of endEditing
, for example, fixes changed attributes and then notifies its layout managers that they need to re-lay and redisplay their text. The default implementations do nothing.
- NSMutableAttributedString为要覆盖的NSMutableAttributedString的子类提供beginEditing和endEditing方法。 这些方法允许子类的实例记录或缓冲更改组,并在收到endEditing消息时自行清理。 endEditing方法还允许接收方通知任何观察者它已被更改。 例如,NSTextStorage的endEditing实现修复了更改的属性,然后通知其布局管理器他们需要重新布局并重新显示其文本。 默认实现什么都不做。