2

我正在为 iOS 开发一个富文本编辑器,使用 aUITextViewNSAttributedString. 它的功能与传统的类似(即选择一个区域,单击一个按钮,并将该效果应用于该区域,同时保留文本上的任何其他属性。

不幸的是NSAttributedString,并不是所有的都可以独立调整。其中一些(至少是粗体、字体和字体大小)都需要传递 a UIFont,它将为该区域设置所有这些属性(即使您只想设置一个)。将单个区域视为可能包含多个面和大小,这将导致幼稚的方法破坏许多现有格式。

有什么推荐的方法来完成这个吗?我在想我唯一的选择是遍历我想要应用它的区域的属性,将它分组为具有相同其他字体属性的块,然后将它单独应用于每个块。

4

2 回答 2

7

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

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

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

于 2013-01-04T17:54:43.440 回答
1

这是我在 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 一起使用。

于 2013-01-05T16:07:14.927 回答