With reference to the answer posted by Asperi (https://stackoverflow.com/users/12299030/asperi) on Question: Highlight a specific part of the text in SwiftUI
I have f
After much discussion in the comments, it became clear that I was hitting a maximum Text() concatenations limit, so beware, apparently there is one.
I realized however that I only needed to have a split Text("Word") when that particular word required special formatting (IE highlighting, etc), otherwise, I could concat all of the raw strings together and send that as a Text("String of words").
This approach mitigated the action of having every single word sent as a Text("Word" by itself and cut down greatly on the number of Text()'s being returned.
see code below that solved the issue:
func hilightedText(str: String) -> Text {
let textToSearch = searched
var result = Text(" ")
var words: String = " "
var foundWord = false
for line in str.split(whereSeparator: \.isNewline) {
for word in line.split(whereSeparator: \.isWhitespace) {
if word.localizedStandardContains(textToSearch) {
foundWord = true
result += Text(words) + Text(" ") + Text(word).bold().foregroundColor(.yellow)
} else {
if foundWord {
words = ""
}
foundWord = false
words += " " + word
}
}
words += "\n\n"
}
return result + Text(" ") + Text(words)
}
extension Text {
static func += (lhs: inout Text, rhs: Text) {
lhs = lhs + rhs
}
}
It could use some cleanup as also discussed in the comments for splitting by whitespace, etc, but this was just to overcome the issue of crashing. Needs some additional testing before I call it good, but no more crashing..
ADDED: the suggestion to use separator by .isWhiteSpace worked, but when I put it back together, everything was a space, no more line breaks, so I added the extra split by line breaks to preserve the line breaks.
Hmm... unexpected limitation... anyway - learn something new.
Ok, here is improved algorithm, which should move that limitation far away.
Tested with Xcode 12 / iOS 14. (also updated code in referenced topic Highlight a specific part of the text in SwiftUI)
func hilightedText(str: String, searched: String) -> Text {
guard !str.isEmpty && !searched.isEmpty else { return Text(str) }
var result = Text("")
var range = str.startIndex..<str.endIndex
repeat {
guard let found = str.range(of: searched, options: .caseInsensitive, range: range, locale: nil) else {
result = result + Text(str[range])
break
}
let prefix = str[range.lowerBound..<found.lowerBound]
result = result + Text(prefix) + Text(str[found]).bold().foregroundColor(.yellow)
range = found.upperBound..<str.endIndex
} while (true)
return result
}