开发者

Objective C - Change all attributes in NSAttributedString?

开发者 https://www.devze.com 2023-03-21 22:19 出处:网络
[attributedStr开发者_如何学运维ing enumerateAttributesInRange:range options:NSAttributedStringEnumerationReverse usingBlock:
[attributedStr开发者_如何学运维ing enumerateAttributesInRange:range options:NSAttributedStringEnumerationReverse usingBlock:
     ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

         NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
         [mutableAttributes setObject:[NSNumber numberWithInt:1] forKey:@"NSUnderline"];
         attributes = mutableAttributes;

     }];

I am trying to loop through all attributed and add NSUnderline to them. when debugging it seems like NSUnderline is added to the dictionary, but when i loop for the second time they are removed. Am I doing anything wrong while updating NSDictionaries?


Jonathan's answer does a good job of explaining why it doesn't work. To make it work, you need to tell the attributed string to use these new attributes.

[attributedString enumerateAttributesInRange:range options:NSAttributedStringEnumerationReverse usingBlock:
     ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

         NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
         [mutableAttributes setObject:[NSNumber numberWithInt:1] forKey:@"NSUnderline"];
         [attributedString setAttributes:mutableAttributes range:range];

 }];

Changing the attributes of an attributed string requires that it is a NSMutableAttributedString.

There is also an easier way to do this. NSMutableAttributedString defines the addAttribute:value:range: method, which sets the value of a specific attribute over the specified range, without changing other attributes. You can replace your code with a simple call to this method (still requiring a mutable string).

[attributedString addAttribute:@"NSUnderline" value:[NSNumber numberWithInt:1] range:(NSRange){0,[attributedString length]}];


You're modifying a local copy of the dictionary; the attributed string does not have any way to see the change.

Pointers in C are passed by value (and thus what they point to is passed by reference.) So when you assign a new value to attributes, the code that called the block has no idea you changed it. The change does not propagate outside of the block's scope.

0

精彩评论

暂无评论...
验证码 换一张
取 消