web-dev-qa-db-fra.com

Boucle via les attributs NSAttributedString pour augmenter la taille de police

Tout ce dont j'ai besoin est de parcourir tous les attributs de NSAttributedString et d'augmenter leur taille de police. Jusqu'à présent, j'en suis arrivé au point où j'ai réussi à parcourir et à manipuler les attributs, mais je ne peux pas enregistrer de nouveau dans NSAttributedString. La ligne que j'ai commentée ne fonctionne pas pour moi. Comment économiser?

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:

 }];
30
Vad

Quelque chose comme ça devrait fonctionner:

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;

À ce stade, res a une nouvelle chaîne attribuée avec toutes les polices deux fois leur taille d'origine.

54
rmaddy

Créez un NSMutableAttributedString à partir de votre chaîne attribuée d'origine avant de commencer. A chaque itération de la boucle, appelez addAttribute:value:range: sur la chaîne attribuée mutable (cela remplacera les anciens attributs de cette plage).

5
Wain

Voici un Swift port de réponse de maddy (qui fonctionne vraiment bien pour moi!). Il est enveloppé dans une petite 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
    }
}
2
Oliver