String munging in Objective-C with NSAttributedString
I have an NSAttributedString s
and an integer i
and I need a function that takes s
and i
and returns a new NSAttributedString that has a (gated) i
appended to s
.
It looks like some combination of -stringWithFormat:
, -initWithString:
and -insertAttributedString:
will do it, but I'm having trouble combining it without a lot of convolutional and temporary variables.
More generally, pointers to a guide to understanding NSAttributedString and NSMutableAttributedString would be great.
source to share
I think I found another way:
// convert it to a mutable string
NSMutableAttributedString *newString;
newString = [[NSMutableAttributedString alloc] initWithAttributedString:old];
// create string containing the number
NSString *numberString = [NSString stringWithFormat:@"%i", i];
// append the number to the new string
[newString replaceCharactersInRange:NSMakeRange([newString length] - 1, 0)
withString:numberString];
I think it works because Apple Documentation says:
- (void) replaceCharactersInRange: (NSRange) aRange withString: (NSString *) aString
The new characters inherit the attributes of the first replaced character from aRange. Where the length of aRange is 0, new characters inherit the attributes of the character preceding aRange if it is any character, otherwise character after aRange.
source to share
Pointers are here: Attribute String Programming Guide
The short answer is to use NSMutableAttributedString - since it inherits from NSAttributedString, you can use it anywhere you would use the (immutable) NSAttributedString.
A newly created NSMAS can strip the content and attributes of the NSAS using the setAttributedString: method. Then you can replace characters for free: InRange: or deleteCharactersInRange: or insertAttributedString: atIndex: for your heart content.
source to share
If you have multiple attribute strings that you want to place in another attribute string, you can use this Category I:
You will need to pass NULL as the last argument to the function, however, otherwise it will fail to the va_list constraints to determine the size.
[attribitedString stringWithFormat: attrFormat, attrArg1, attrArg2, NULL];
@implementation NSAttributedString(stringWithFormat)
+(NSAttributedString*)stringWithFormat:(NSAttributedString*)format, ...{
va_list args;
va_start(args, format);
NSMutableAttributedString *mutableAttributedString = (NSMutableAttributedString*)[format mutableCopy];
NSString *mutableString = [mutableAttributedString string];
while (true) {
NSAttributedString *arg = va_arg(args, NSAttributedString*);
if (!arg) {
break;
}
NSRange rangeOfStringToBeReplaced = [mutableString rangeOfString:@"%@"];
[mutableAttributedString replaceCharactersInRange:rangeOfStringToBeReplaced withAttributedString:arg];
}
va_end(args);
return mutableAttributedString;
}
@end
source to share