Is there a way in SwiftUI to change the color for special characters in a string?

Viewed 537

I'm trying to build a Thai language app. To show the sound of a Thai word, I want to use these three special characters "\ / -". For readability, I would like to change the color for these characters to red. Is there a way to do it in SwiftUI?

I'm using this as Model:

struct Alphabet {
    var letter: String
    var byname: String
    var translation: String
    var consonantClass: ConsonantClass
}

This is the Viewmodel:

let middleConsonants: [Alphabet] = [
    Alphabet(letter: "ก", byname: "gô:- gai\\", translation: "Chicken", consonantClass: .middle)
]

And here, in the View, I would like to show it with the different colors:

struct ConsonantsListView: View {
    var vm: ConsonantsViewModel = ConsonantsViewModel()
    var consonants: [Alphabet]
    
    var body: some View {
        ForEach(0..<consonants.count, id: \.self) { index in
            HStack {
                Spacer()
                NavigationLink(destination:
                    VStack(spacing: 20) {
                        Text(consonants[index].byname)
                            .font(.largeTitle)
                        Text(consonants[index].translation)
                    }) {
                        Text(consonants[index].letter)
                            .font(.largeTitle)
                }
                Spacer()
            }
        }
    }
}
2 Answers

In SwiftUI you can easily concatenate Text objects with the + operator and assign different colors.

For example this displays a red "Hello" followed by a green "World!"

 Text("Hello ")
        .foregroundColor(.red)
        + Text("World!")
        .foregroundColor(.green)

In iOS 15 attributed text will be available, which will make this very easy.

Until then, you can create a Text for each character (or substring) in one color:

func textRedSpecialCharacters(input: String) -> some View {
        let chars = ["\\", "/", "-"]
        
        return HStack(spacing: 0) {
            ForEach(0..<input.count, id: \.self) { index in
                let char = String(input[input.index(input.startIndex, offsetBy: index)])
                if chars.contains(char) {
                    Text(char).foregroundColor(.red).font(.largeTitle)
                } else {
                    Text(char).font(.largeTitle)
                }
            }
        }
    }

Just a simple example, but works great for your code.

Related