对部分 NSAttributedString 应用粗体,同时保留字体大小和面
Posted
技术标签:
【中文标题】对部分 NSAttributedString 应用粗体,同时保留字体大小和面【英文标题】:Apply bolding to portion of NSAttributedString, while preserving font sizes and faces 【发布时间】:2013-01-04 16:47:57 【问题描述】:我正在开发适用于 ios 的富文本编辑器,使用 UITextView
和 NSAttributedString
。它的功能类似于传统的(即选择一个区域,单击一个按钮,并将该效果应用于该区域,同时保留文本上的任何其他属性。
不幸的是NSAttributedString
,并不是所有的都可以独立调整。其中一些(至少是粗体、字体和字体大小)都需要传递一个UIFont
,它将为该区域设置所有这些属性(即使您只想设置一个)。将单个区域视为可能包含多个面和大小,这将导致幼稚的方法破坏许多现有格式。
有没有推荐的方法来完成这个?我认为我唯一的选择是遍历我想要应用它的区域的属性,将其分组为具有相同其他字体属性的块,然后将其分别应用于每个块。
【问题讨论】:
【参考方案1】:你的想法是对的,enumerateAttribute:inRange:options:usingBlock:
已经为你提供了算法。要使用它来处理字体运行:
[myAttributedString enumerateAttribute:NSFontAttributeName
inRange:selectedRange
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
usingBlock:addBoldBlock
]
其中 addBoldBlock 采用当前字体(作为块的第一个参数提供),添加粗体,并将其应用于当前块(作为块的第二个参数提供)。
【讨论】:
【参考方案2】:这是我在 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 一起使用。
【讨论】:
以上是关于对部分 NSAttributedString 应用粗体,同时保留字体大小和面的主要内容,如果未能解决你的问题,请参考以下文章
UIButton 上的 iOS NSAttributedString
如何将函数调用(不是超链接)添加到 UILabel 中的 NSAttributedString 的一部分?
调用 NSAttributedString.boundingRectWithSize 时应用程序崩溃