将粗体应用于NSAttributedString的一部分,同时保留字体大小和面

我正在使用iOS的富文本编辑器,使用UITextViewNSAttributedString 。 它的function与传统的相似(即选择区域,单击按钮,并将该效果应用于该区域,同时保留文本上的任何其他属性。

不幸的是,使用NSAttributedString ,并非所有这些都可以独立调整。 其中一些(至少是粗体,字体和字体大小)都需要传递一个UIFontUIFont为该区域设置所有这些属性(即使您只想设置一个)。 看作单个区域可能包括多个面和大小,这将导致天真的方法打破了许多现有的格式。

有没有推荐的方法来实现这一目标? 我认为我唯一的选择是迭代我想要应用它的区域的属性,将其分组为具有相同其他字体属性的块,然后单独应用于每个块。

你有正确的想法, enumerateAttribute:inRange:options:usingBlock:已经为你提供了算法enumerateAttribute:inRange:options:usingBlock: . 要使用它来处理字体运行:

 [myAttributedString enumerateAttribute:NSFontAttributeName inRange:selectedRange options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:addBoldBlock ] 

其中addBoldBlock获取当前字体(作为块的第一个参数提供),添加粗体,并将其应用于当前块(作为块的第二个参数提供)。

这是我在DTRichTextEditor中使用的内容:

 - (void)toggleBoldInRange:(NSRange)range { // first character determines current boldness NSDictionary *currentAttributes = [self typingAttributesForRange:range]; if (!currentAttributes) { return; } [self beginEditing]; CTFontRef currentFont = (__bridge CTFontRef)[currentAttributes objectForKey:(id)kCTFontAttributeName]; DTCoreTextFontDescriptor *typingFontDescriptor = [DTCoreTextFontDescriptor fontDescriptorForCTFont:currentFont]; // need to replace name with family CFStringRef family = CTFontCopyFamilyName(currentFont); typingFontDescriptor.fontFamily = (__bridge NSString *)family; CFRelease(family); typingFontDescriptor.fontName = nil; NSRange attrRange; NSUInteger index=range.location; while (index < NSMaxRange(range)) { NSMutableDictionary *attrs = [[self attributesAtIndex:index effectiveRange:&attrRange] mutableCopy]; CTFontRef currentFont = (__bridge CTFontRef)[attrs objectForKey:(id)kCTFontAttributeName]; if (currentFont) { DTCoreTextFontDescriptor *desc = [DTCoreTextFontDescriptor fontDescriptorForCTFont:currentFont]; // need to replace name with family CFStringRef family = CTFontCopyFamilyName(currentFont); desc.fontFamily = (__bridge NSString *)family; CFRelease(family); desc.fontName = nil; desc.boldTrait = !typingFontDescriptor.boldTrait; CTFontRef newFont = [desc newMatchingFont]; [attrs setObject:(__bridge id)newFont forKey:(id)kCTFontAttributeName]; CFRelease(newFont); if (attrRange.location < range.location) { attrRange.length -= (range.location - attrRange.location); attrRange.location = range.location; } if (NSMaxRange(attrRange)>NSMaxRange(range)) { attrRange.length = NSMaxRange(range) - attrRange.location; } [self setAttributes:attrs range:attrRange]; } index += attrRange.length; } [self endEditing]; } 

这使用来自开源DTCoreText项目的DTCoreTextFontDescriptor。

PS:您必须相应调整它以便与UIFont一起使用。