Last Run on XCODE 11.6 / Swift 5.2

Definitions Link to heading

‘TextField’ is a View provided in SwiftUI for handling user entered input into an app. As per the documentaion, Apple defines it as

“TextField - A control that displays an editable text interface.”

struct TextFieldEditMode: View {
    @State private var someData = ""
    var body: some View {
        TextField("Type something", text: $someData)
            .font(.largeTitle)
    }
}

Initializers Link to heading

The ‘TextField’ has four initializers, and the one we will be using in this post is the one listed below, that provides us with two additional parameters “onEditingChanged” and “onCommit”.

    init<S>(S, text: Binding<String>, onEditingChanged: (Bool) -> Void, 
    onCommit: () -> Void)

Implementation - Basic Link to heading

The parameter onEditingChanged() takes a closure of the type ‘(Bool) -> Void’ that we as developers need to provide to inject additional functionality. The closure recives a bool value signifying if the TextField is in editMode. Interestingly, this closure also gets triggered on entering the return key.

Lets get started. In the code below, I will update a Text View with the bool value recived by the onEditingChanged() method once we start entering into the field.

struct TextFieldEditMode: View {
    @State private var someData = ""
    @State private var editFlag = false
    var body: some View {
        VStack {
            Text("Editting Status: \(editFlag.description)")
            TextField("Type something", text: $someData,
                      onEditingChanged: { isBeingEditted in
                        self.editFlag = isBeingEditted
            })
                .font(.largeTitle)
        }
    }
}
TextField not being editted. TextField being editted.
SwiftUI TextField Off SwiftUI TextField On

Implementation - Color Menu Link to heading

Let’s make something more practical with our learnings. In the code below, we add a ColorMenu() View above the TextField to allow the user to change the foreground color of the input text.

    @State private var someData = ""
    @State private var editFlag = false
    @State private var foregroundColor = Color.primary
    var body: some View {
        VStack {
            if editFlag {
                ColorMenu(foregroundColor: $foregroundColor)
            }
            TextField("Type something", text: $someData,
                      onEditingChanged: { isBeingEditted in
                        self.editFlag = isBeingEditted
            })
                .font(.largeTitle)
                .foregroundColor(foregroundColor)
        }
    }

This is the basic implementation of the ColorMenu() View that we conditionally make visible in our app based on the edit status of the TextField.

struct ColorMenu: View {
    @Binding var foregroundColor: Color
    var body: some View {
        HStack {
            Button(action: {self.foregroundColor = .red}) {
                Image(systemName: "circle.fill").foregroundColor(.red)
            }
            Spacer()
            Button(action: {self.foregroundColor = .yellow}) {
                Image(systemName: "circle.fill").foregroundColor(.yellow)
            }
            Spacer()
            Button(action: {self.foregroundColor = .blue}) {
                Image(systemName: "circle.fill").foregroundColor(.blue)
            }
            Spacer()
            Button(action: {self.foregroundColor = .green}) {
                Image(systemName: "circle.fill").foregroundColor(.green)
            }
            Spacer()
            Button(action: {self.foregroundColor = .orange}) {
                Image(systemName: "circle.fill").foregroundColor(.orange)
            }
        }
    }
}

TextField onEditingChanged() Demo