user13500355
user13500355

Reputation:

UITextField custom background color when editing

I'm trying to give a background color to a UITextField using SwiftUI since I'm trying to use some unique colours in my app to support both LightMode and DarkMode.

My colors are always defined as a ColorSet in the xcassets folder and this is the code I was using at first to achieve this background color.

TextField("Exam title", text: $title)
    .padding()
    .background(Color("cardBackground"))
    .cornerRadius(8)

This way I'm able to change the background color of the TextField when I'm not using it. This is how's the outcome of this

Correct Look

The problem I'm facing is that as soon as I tap on the TextField it goes back to its default color (I think it is the default one) and I'm unable to change that.

When editing

So what I did was creating a UIViewRepresentable implementation of the TextField, maybe that could have helped me much more than SwiftUI can do at this stage.

struct CustomUIKitTextField: UIViewRepresentable {

    @Binding var text: String
    var placeholder: String
    var backgroundColor: UIColor = .red

    func makeUIView(context: UIViewRepresentableContext<CustomUIKitTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        textField.placeholder = placeholder
        textField.backgroundColor = backgroundColor
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomUIKitTextField>) {
        uiView.text = text
        uiView.backgroundColor = backgroundColor
        uiView.setContentHuggingPriority(.defaultHigh, for: .vertical)
        uiView.setContentCompressionResistancePriority(.required, for: .vertical)
    }

    func makeCoordinator() -> CustomUIKitTextField.Coordinator {
        Coordinator(parent: self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: CustomUIKitTextField

        init(parent: CustomUIKitTextField) {
            self.parent = parent
        }

        func textFieldDidChangeSelection(_ textField: UITextField) {
            parent.text = textField.text ?? ""
        }

        func textFieldDidBeginEditing(_ textField: UITextField) {
            print("Begin editing")
            textField.backgroundColor = .brown
        }

        func textFieldDidEndEditing(_ textField: UITextField) {
            print("Finished Editing")
        }

    }
}

I've tried something as you can see (there are some things to just debug stuff) but I'm not that much experienced in UIKit so I don't really know what is the best way to tackle this problem and out there there's not much about this kind of problem.

Have you faced something similar before? How can I solve this problem?

EDIT:

If this can help this is the view hierarchy when the TextField is in editing mode and the selected elements that puts itself in front of the TextField is a UIFieldEditor

UIFieldEditor

Upvotes: 3

Views: 1880

Answers (1)

Attila Marosi
Attila Marosi

Reputation: 174

first off, don't define background colour in SwiftUI:
.background(Color("cardBackground")) / remove this line of code

In the makeUIView method, setup a default background color, which is used, when user not tapping the textfield:

textfield.backgroundColor = .systemGray

Finally, use these methods in the Coordinator class to control background colour behaviour:

    func textFieldDidBeginEditing(_ textField: UITextField) {
        textField.backgroundColor = .red
    }

    func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
        textField.backgroundColor = .systemGray
    }

Upvotes: 1

Related Questions