Search code examples
swiftstringsearchtextswiftui

Highlight a specific part of the text


I'm new to Swift and I am using SwiftUI for my project where I download some weather data and I display it in the ContentView().

I would like to highlight some part of the Text if it contains some specific word, but I don't have any idea how to start.

In ContentView(), I have tried to set a function receiving the string downloaded from web and return a string. I believe this is wrong, because SwiftUI does not apply the modifiers at the all for the Text.

For example, in my ContentView() I would like the word thunderstorm to have the .bold() modifier:

struct ContentView: View {
  let testo : String = "There is a thunderstorm in the area"
  
  var body: some View {
    Text(highlight(str: testo))
  }
  
  func highlight(str: String) -> String {
    let textToSearch = "thunderstorm"
    var result = ""
    
    if str.contains(textToSearch) {
      let index = str.startIndex
      result = String( str[index])
    }
    
    return result
  }
  
}

Solution

  • iOS 13, Swift 5. There is a generic solution described in this medium article. Using it you can highlight any text anywhere with the only catch being it cannot be more then 64 characters in length, since it using bitwise masks.

    https://medium.com/@marklucking/an-interesting-challenge-with-swiftui-9ebb26e77376

    enter image description here

    This is the basic code in the article.

    ForEach((0 ..< letter.count), id: \.self) { column in
          Text(letter[column])
            .foregroundColor(colorCode(gate: Int(self.gate), no: column) ? Color.black: Color.red)
            .font(Fonts.futuraCondensedMedium(size: fontSize))
    
        }
    

    And this one to mask the text...

    func colorCode(gate:Int, no:Int) -> Bool {
    
     let bgr = String(gate, radix:2).pad(with: "0", toLength: 16)
     let bcr = String(no, radix:2).pad(with: "0", toLength: 16)
     let binaryColumn = 1 << no - 1
    
     let value = UInt64(gate) & UInt64(binaryColumn)
     let vr = String(value, radix:2).pad(with: "0", toLength: 16)
    
     print("bg ",bgr," bc ",bcr,vr)
     return value > 0 ? true:false
    }