Objective c 设置NSAttribute字符串属性将覆盖子字符串属性

Objective c 设置NSAttribute字符串属性将覆盖子字符串属性,objective-c,nsattributedstring,Objective C,Nsattributedstring,我创建了一个可变字符串,它看起来像@“testMeIn:greenColor:Different:greenColor:Colors” 当我添加属性foregroundColor时,子字符串中现有的绿色将被指定的黑色覆盖。虽然我可以更改代码以设置子字符串的绿色,但我想知道是否有其他方法可以将样式应用到没有样式的字符串部分,而不覆盖现有样式 您可以枚举字符串中的每个属性范围,并且仅在尚未设置属性时更改属性 NSMutableAttributedString* aString = [[NSMu

我创建了一个可变字符串,它看起来像@“testMeIn:greenColor:Different:greenColor:Colors


当我添加属性foregroundColor时,子字符串中现有的绿色将被指定的黑色覆盖。虽然我可以更改代码以设置子字符串的绿色,但我想知道是否有其他方法可以将样式应用到没有样式的字符串部分,而不覆盖现有样式

您可以枚举字符串中的每个属性范围,并且仅在尚未设置属性时更改属性

 NSMutableAttributedString* aString = 
 [[NSMutableAttributedString alloc] initWithString:@"testMeIn DIFFERENT Colors"];

 [aString setAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]} 
                  range:(NSRange){9,9}];

 [aString enumerateAttributesInRange:(NSRange){0,aString.length}
                             options:nil
                          usingBlock:
     ^(NSDictionary* attrs, NSRange range, BOOL *stop) {

          //unspecific: don't change text color if ANY attributes are set
         if ([[attrs allKeys] count]==0)
             [aString addAttribute:NSForegroundColorAttributeName 
                             value:[UIColor redColor] 
                             range:range];

         //specific: don't change text color if text color attribute is already set
         if (![[attrs allKeys] containsObject:NSForegroundColorAttributeName])
             [aString addAttribute:NSForegroundColorAttributeName 
                             value:[UIColor redColor] 
                             range:range];
     }];

谢谢,这应该有用。但我担心,当样式频繁变化时,这可能会成为一项成本高昂的操作。在一个长字符串中添加不同的样式。
 NSMutableAttributedString* aString = 
 [[NSMutableAttributedString alloc] initWithString:@"testMeIn DIFFERENT Colors"];

 [aString setAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]} 
                  range:(NSRange){9,9}];

 [aString enumerateAttributesInRange:(NSRange){0,aString.length}
                             options:nil
                          usingBlock:
     ^(NSDictionary* attrs, NSRange range, BOOL *stop) {

          //unspecific: don't change text color if ANY attributes are set
         if ([[attrs allKeys] count]==0)
             [aString addAttribute:NSForegroundColorAttributeName 
                             value:[UIColor redColor] 
                             range:range];

         //specific: don't change text color if text color attribute is already set
         if (![[attrs allKeys] containsObject:NSForegroundColorAttributeName])
             [aString addAttribute:NSForegroundColorAttributeName 
                             value:[UIColor redColor] 
                             range:range];
     }];