Split Attributed String and Preserve Formatting
How can you take an existing NSAttributedString and split it based on a predefined delimiter while preserving the formatting? It looks like the SeparatedByString components will work on NSAttributedString.
My current workaround creates breaks at the correct points, but only outputs the NSString. Thus, formatting is lost.
NSData *rtfFileData = [NSData dataWithContentsOfFile:path];
NSAttributedString *rtfFileAttributedString = [[NSAttributedString alloc] initWithData:rtfFileData options:@{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil];
NSString *rtfFileString = [rtfFileAttributedString string];
NSString *importSeparator = @"###";
// Wish I could do this
// NSArray *separatedArray = [rtfFileAttributedString componentsSeparatedByString:importSeparatorPref];
NSArray *separatedArray = [rtfFileString componentsSeparatedByString:importSeparatorPref];
NSLog( @"Separated array: %@", separatedArray );
+3
source to share
4 answers
You can use your split unbound string to split the attribute string. One of the options:
NSData *rtfFileData = [NSData dataWithContentsOfFile:path];
NSAttributedString *rtfFileAttributedString = [[NSAttributedString alloc] initWithData:rtfFileData options:@{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil];
NSString *rtfFileString = [rtfFileAttributedString string];
NSString *importSeparator = @"###";
NSArray *separatedArray = [rtfFileString componentsSeparatedByString:importSeparatorPref];
NSMutableArray *separatedAttributedArray = [NSMutableArray arrayWithCapacity:separatedArray.count];
NSInteger start = 0;
for (NSString *sub in separatedArray) {
NSRange range = NSMakeRange(start, sub.length);
NSAttributedString *str = [rtfFileAttributedString attributedSubstringFromRange:range];
[separatedAttributedArray addObject:str];
start += range.length + importSeparator.length;
}
NSLog(@"Separated attributed array: ", separatedAttributedArray);
+11
source to share
In Swift 4, I made a function.
func splitAttributedString(inputString: NSAttributedString, seperateBy: String) -> [NSAttributedString] {
let input = inputString.string
let separatedInput = input.components(separatedBy: seperateBy)
var output = [NSAttributedString]()
var start = 0
for sub in separatedInput {
let range = NSMakeRange(start, sub.utf16.count)
let attribStr = inputString.attributedSubstring(from: range)
output.append(attribStr)
start += range.length + seperateBy.count
}
return output
}
+3
source to share
The quick answer is simple.
var string = NSAttributedString(
string: "This string is shorter than it should be for this questions answer.",
attributes: [.font: UIFont.systemFont(ofSize: 12)]
)
let range = NSRange(location: 0, length: 120)
let newString = string.attributedSubstring(from: range)
print(newString)
0
source to share
Here's an extension NSAttributedString
that works similar to some of the other examples here.
private extension NSAttributedString {
func components(separatedBy separator: String) -> [NSAttributedString] {
var result = [NSAttributedString]()
let separatedStrings = string.components(separatedBy: separator)
var range = NSRange(location: 0, length: 0)
for string in separatedStrings {
range.length = string.utf16.count
let attributedString = attributedSubstring(from: range)
result.append(attributedString)
range.location += range.length + separator.utf16.count
}
return result
}
}
0
source to share