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


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


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


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







All Articles