簡體   English   中英

屬性文本,使用swift將一種特定的字體替換為另一種

[英]Attributed text, replace a specific font by another using swift

我在UITextView中使用屬性文本。 文本包含許多字體。

我正在尋找一種將另一種字體替換為另一種字體的方法。

有什么快速的方法嗎? :)

有一個稱為attributesAtIndex(_:effectiveRange:) 此方法返回一個字典,您可以從中獲取字體。

您將需要遍歷每個索引來存儲字體。 這會很慢,因為在文本文件中,字體可能會更改每個字符。 因此,我建議在主線程之外執行此操作。

我的代碼將在Objective-C中進行,但是由於我們同時使用了CocoaTouch,因此邏輯應該相同。

我使用的方法是enumerateAttribute:inRange:options:usingBlock:僅查找NSFontAttributeName

還有一點沒有討論:如何識別字體是搜索到的字體。 您是否要查找familyNamefontNameUIFont屬性?即使在同一個家族中,字體看起來也可能有很大不同,並且您可能想真正地搜索完全匹配相同名稱的字體。我在這里曾經討論過Font Names。您可能會發現這種情況很有趣,請注意,有些方法(當時我還不知道)可以獲取字體的粗體(如果可用)(或斜體等)。

Objective-C中的主要代碼是以下代碼:

[attrString enumerateAttribute:NSFontAttributeName
                           inRange:NSMakeRange(0, [attrString length])
                           options:0
                        usingBlock:^(id value, NSRange range, BOOL *stop) {
                            UIFont *currentFont = (UIFont *)value; //Font currently applied in this range
                            if ([self isFont:currentFont sameAs:searchedFont]) //This is where it can be tricky
                            {
                            [attrString addAttribute:NSFontAttributeName
                                               value:replacementFont
                                               range:range];
                            }
    }];

根據您的需要可能的更改/適應:更改字體,但不更改大小:

[attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:replaceFontName size:currentFont.pointSize]; range:range];

測試代碼示例:

UIFont *replacementFont = [UIFont boldSystemFontOfSize:12];
UIFont *searchedFont    = [UIFont fontWithName:@"Helvetica Neue" size:15];
UIFont *normalFont      = [UIFont italicSystemFontOfSize:14];

NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:@"Lorem ipsum dolor sit amet,"];

NSAttributedString *attrStr1 = [[NSAttributedString alloc] initWithString:@"consectetuer adipiscing elit." attributes:@{NSFontAttributeName:searchedFont, NSForegroundColorAttributeName:[UIColor redColor]}];

NSAttributedString *attrStr2 = [[NSAttributedString alloc] initWithString:@" Aenean commodo ligula eget dolor." attributes:@{NSFontAttributeName:normalFont}];

NSAttributedString *attrStr3 = [[NSAttributedString alloc] initWithString:@" Aenean massa." attributes:@{NSFontAttributeName:searchedFont}];

NSAttributedString *attrStr4 = [[NSAttributedString alloc] initWithString:@"Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim."];

[attrString appendAttributedString:attrStr1];
[attrString appendAttributedString:attrStr2];
[attrString appendAttributedString:attrStr3];
[attrString appendAttributedString:attrStr4];

NSLog(@"AttrString: %@", attrString);

[attrString enumerateAttribute:NSFontAttributeName
                       inRange:NSMakeRange(0, [attrString length])
                       options:0
                    usingBlock:^(id value, NSRange range, BOOL *stop) {
                        UIFont *currentFont = (UIFont *)value;
                        if ([self isFont:currentFont sameAs:searchedFont])
                        {
            [attrString addAttribute:NSFontAttributeName
                               value:replacementFont
                               range:rangeEffect];
                        }
}];

NSLog(@"AttrString Changed: %@", attrString);

使用@TigerCoding的解決方案,這里是可能的代碼:

NSInteger location = 0;
while (location < [attrString length])
{
    NSRange rangeEffect;
    NSDictionary *attributes = [attrString attributesAtIndex:location effectiveRange:&rangeEffect];
    if (attributes[NSFontAttributeName])
    {
        UIFont *font = attributes[NSFontAttributeName];
        if ([self isFont:font sameAs:searchedFont])
        {
            [attrString addAttribute:NSFontAttributeName value:replacementFont range:rangeEffect];
        }
    }
    location+=rangeEffect.length;
}

附帶說明:進行一些優化測試(但需要進行一些研究)。 我想舉幾個例子,如果您對兩個連續的范圍應用相同的attributeS,則NSAttributedString會將它們“附加”為一個,以防您可能害怕連續應用相同的效果。 所以問題是,如果您有@{NSFontAttributeName:font1, NSForegroundColorAttributeName:color1}的范圍為0,3和@{NSFontAttributeName:font1, NSForegroundColorAttributeName:color2} @{NSFontAttributeName:font1, NSForegroundColorAttributeName:color1}的范圍為3,5將會enumerateAttribute:inRange:options:usingBlock:返回您0.5的范圍? 它會比枚舉每個索引更快嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM