Make NSAttributedString extension allow multiple palceholder string replacements (IOS-140)

This commit is contained in:
Marcus Kida 2023-05-05 14:48:02 +02:00
parent 2f4ce19983
commit f63b56bbf2
No known key found for this signature in database
GPG Key ID: 19FF64E08013CA40
1 changed files with 35 additions and 4 deletions

View File

@ -6,11 +6,42 @@ public extension NSAttributedString {
convenience init(format: NSAttributedString, args: NSAttributedString...) {
let mutableNSAttributedString = NSMutableAttributedString(attributedString: format)
args.forEach { attributedString in
let range = NSString(string: mutableNSAttributedString.string).range(of: "%@")
mutableNSAttributedString.replaceCharacters(in: range, with: attributedString)
zip(format.string.ranges(of: "%@"), Array(args)).forEach { range, arg in
mutableNSAttributedString.replaceCharacters(in: .init(range: range, originalText: format.string), with: arg)
}
self.init(attributedString: mutableNSAttributedString)
}
}
private extension String {
func ranges(of searchString: String) -> [Range<String.Index>] {
let indices = indices(of: searchString)
let count = searchString.count
return indices.map({ index(startIndex, offsetBy: $0)..<index(startIndex, offsetBy: $0+count) })
}
func indices(of occurrence: String) -> [Int] {
var indices = [Int]()
var position = startIndex
while let range = range(of: occurrence, range: position..<endIndex) {
let i = distance(from: startIndex, to: range.lowerBound)
indices.append(i)
let offset = occurrence.distance(from: occurrence.startIndex, to: occurrence.endIndex) - 1
guard let after = index(range.lowerBound, offsetBy: offset, limitedBy: endIndex) else {
break
}
position = index(after: after)
}
return indices
}
}
private extension NSRange {
init(range: Range<String.Index>, originalText: String) {
self.init(
location: range.lowerBound.utf16Offset(in: originalText),
length: range.upperBound.utf16Offset(in: originalText) - range.lowerBound.utf16Offset(in: originalText)
)
}
}