2

I'm stuck on a problem with SwiftUI. I need to color all the letters red and all the numbers black in a TextField while the user is typing them.

Let's say I have this code

TextField(
     "A99",
     text: $viewModel.code
)
.padding([.trailing])
.multilineTextAlignment(.trailing)

How would I achieve my goal of colouring while the user types?

I'm pretty new to iOS development, also new to SwiftUi and never really used UIKit, so the answer might be obvious but I couldn't find one.

alessandro gaboardi
  • 889
  • 3
  • 11
  • 26

2 Answers2

0

You can try this way for short texts for Now! Not the final Answer!

struct ContentView: View {
    
    @State private var string: String = "A99"
    
    var body: some View {
        
        CustomTextFieldView(titleKey: "Enter your text here ...", string: $string)
        
    }
    
}




struct CustomTextFieldView: View {
    
    let titleKey: LocalizedStringKey
    let letterColor: Color = .red
    let numberColor: Color = .black
    @Binding var string: String
    
    var body: some View {
        
        HStack(spacing: .zero) {
            
            ForEach(Array(string), id:\.self) { index in
                
                Text(String(describing: index)).foregroundColor(Int(String(describing: index)) != nil ? numberColor : letterColor)
                
            }

            Spacer()

        }
        .overlay(TextField(titleKey, text: $string).foregroundColor(.clear), alignment: .topLeading)
        
    }
    
}
ios coder
  • 1
  • 4
  • 31
  • 91
0

somewhat crude, but working well for me. The approach is to put a transparent TextField on top of a Text that does all the attributed string functions. You will have to adjust the code for multilines etc...

struct ContentView: View {
    @State var txt = "A99"
    
    var body: some View {
        ZStack (alignment: .leading) {
            Text(txt) { str in
                var temp: AttributedString = ""
                for char in txt {
                    var charx = AttributedString(String(char))
                    charx.foregroundColor = char.isLetter ? .red : .black
                    temp.append(charx)
                }
                str = temp
            }
            TextField("", text: $txt).foregroundColor(.clear)
        }.frame(width: 222, height: 33).border(.green)
    }
}

EDIT1: include the required Text extension from: How to use Attributed String in SwiftUI

extension Text {
    init(_ string: String, configure: ((inout AttributedString) -> Void)) {
        var attributedString = AttributedString(string) /// create an `AttributedString`
        configure(&attributedString) /// configure using the closure
        self.init(attributedString) /// initialize a `Text`
    }
}
  • Which version of SwiftUI or Xcode needed to run your code? `Trailing closure passed to parameter of type 'Formatter' that does not accept a closure` – ios coder Oct 11 '21 at 13:57
  • Sorry, I did not realised I was using an extension (provided by @aheze) from this SO answer: https://stackoverflow.com/questions/59531122/how-to-use-attributed-string-in-swiftui (last answer) I'll update my answer. I'm on macos 12.beta9, xcode 13.beta5 (not release), targets ios 15 and macCatalyst 12. Does not work on macos12 only app. – workingdog support Ukraine Oct 11 '21 at 23:01