Подтвердить что ты не робот

Зацикливание через атрибуты NSAttributedString для увеличения шрифта SIze

Мне нужно всего лишь перебрать все атрибуты NSAttributedString и увеличить размер шрифта. До сих пор я дошел до того, что успешно прошел цикл и манипулировал атрибутами, но я не могу сэкономить на NSAttributedString. Строка, которую я прокомментировал, не работает для меня. Как сохранить обратно?

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:

 }];
4b9b3361

Ответ 1

Что-то вроде этого должно работать:

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;

В этот момент res добавлена ​​новая атрибутная строка со всеми шрифтами, в два раза превышающими их первоначальный размер.

Ответ 2

Создайте NSMutableAttributedString из исходной атрибутной строки перед началом работы. На каждой итерации цикла вызовите addAttribute:value:range: в изменяемой атрибутной строке (это заменит старые атрибуты в этом диапазоне).

Ответ 3

Вот ответ Swift Port of Maddy (который очень хорошо работает для меня!). Это завернуто в небольшое расширение.

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
    }
}