I think the WWDC talk was Combine In Practice, but that example used UIKit.
The thing to remember is that in SwiftUI, views are a function of state, nothing more. Your state is what drives everything—you can't get things from a View instance, you have to bind the view to some state, then use the state to influence your decisions. In keeping with that, you would bind your text field to some state and then use that state in your view rendering code.
For your simple example, you could set your text field to just use the `input` variable directly to display what's being typed. If you specifically want to assign the final result to a different variable, you can use the `onCommit` handler to do that. Meanwhile, the `onEditingChanged` handler isn't referring to 'the user edited the field so its value changed', it means 'the "isEditing" property of the text field has changed' — it hands you a Bool telling you whether it's now editing or not.
A version of your simple example that does exactly what you describe appears below; note the use of a third state variable used to determine whether to print "You are typing:" or "You typed:" based on the `isEditing` property of the text field:
import SwiftUI
struct ContentView: View {
@State var output: String = ""
@State var input: String = ""
@State var typing = false
var body: some View {
VStack {
if !typing {
if !output.isEmpty {
Text("You typed: \(output)")
}
} else if !input.isEmpty {
Text("You are typing: \(input)")
}
TextField("", text: $input, onEditingChanged: {
self.typing = $0
}, onCommit: {
self.output = self.input
})
.background(Color.green.opacity(0.2))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}