简体   繁体   English

循环遍历 NSAttributedString 属性以增加字体大小

[英]Looping Through NSAttributedString Attributes to Increase Font SIze

All I need is to loop through all attributes of NSAttributedString and increase their font size.我只需要遍历NSAttributedString的所有属性并增加它们的字体大小。 So far I got to the point where I successfully loop through and manipulate attributes but I cannot save back to NSAttributedString .到目前为止,我已经成功循环并操作属性,但我无法保存回NSAttributedString The line I commented out is not working for me.我注释掉的那行对我不起作用。 How to save back?怎么挽回?

NSAttributedString *attrString = self.richTextEditor.attributedText;

[attrString enumerateAttributesInRange: NSMakeRange(0, attrString.string.length)
                               options:NSAttributedStringEnumerationReverse usingBlock:
 ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

     NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];        

     UIFont *font = [mutableAttributes objectForKey:NSFontAttributeName];
     UIFont *newFont = [UIFont fontWithName:font.fontName size:font.pointSize*2];         
     [mutableAttributes setObject:newFont forKey:NSFontAttributeName];
     //Error: [self.richTextEditor.attributedText setAttributes:mutableAttributes range:range];
     //no interfacce for setAttributes:range:

 }];

Something like this should work: 这样的事情应该有效:

NSMutableAttributedString *res = [self.richTextEditor.attributedText mutableCopy];

[res beginEditing];
__block BOOL found = NO;
[res enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, res.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
    if (value) {
        UIFont *oldFont = (UIFont *)value;
        UIFont *newFont = [oldFont fontWithSize:oldFont.pointSize * 2];
        [res removeAttribute:NSFontAttributeName range:range];
        [res addAttribute:NSFontAttributeName value:newFont range:range];
        found = YES;
    }
}];
if (!found) {
    // No font was found - do something else?
}
[res endEditing];
self.richTextEditor.attributedText = res;

At this point res has a new attributed string with all fonts being twice their original size. 此时res有一个新的属性字符串,所有字体都是原始大小的两倍。

Create an NSMutableAttributedString from your original attributed string before you start. 在开始之前,从原始属性字符串创建NSMutableAttributedString On each iteration of the loop, call addAttribute:value:range: on the mutable attributed string (this will replace the old attributes in that range). 在循环的每次迭代中,在可变属性字符串上调用addAttribute:value:range:这将替换该范围内的旧属性。

Here is a Swift port of maddy's answer (which works really well for me!). 这是一个Maddy回答的Swift端口(对我来说效果很好!)。 It's wrapped in a little extension. 它包裹在一个小扩展。

import UIKit

extension NSAttributedString {
    func changeFontSize(factor: CGFloat) -> NSAttributedString {
        guard let output = self.mutableCopy() as? NSMutableAttributedString else {
            return self
        }

        output.beginEditing()
        output.enumerateAttribute(NSAttributedString.Key.font,
                                  in: NSRange(location: 0, length: self.length),
                                  options: []) { (value, range, stop) -> Void in
            guard let oldFont = value as? UIFont else {
                return
            }
            let newFont = oldFont.withSize(oldFont.pointSize * factor)
            output.removeAttribute(NSAttributedString.Key.font, range: range)
            output.addAttribute(NSAttributedString.Key.font, value: newFont, range: range)
        }
        output.endEditing()

        return output
    }
}

if You need the exact opposite behaviour, ie change font but keeping other attributes, see here:如果您需要完全相反的行为,即更改字体但保留其他属性,请参见此处:

NSAttributedString, change the font overall BUT keep all other attributes? NSAttributedString,整体更改字体但保留所有其他属性?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM