swiftswiftuiviewtextfield

How to get @FocusState property to work when TextField is on .sheet


I have the following simple code which places a Button on a View and when tapped, presents a TextField on a .sheet:

struct TestView: View
{
    @State private var sheetIsPresented: Bool = false
    @State private var userInput: String = ""
    @FocusState private var textFieldIsFocused: Bool
    
    var body: some View
    {
        Button("Hello")
        {
            self.sheetIsPresented = true
        }
        .buttonStyle(.borderedProminent)
        .sheet(isPresented: self.$sheetIsPresented)
        {
            HStack
            {
                Text("Name:")
                TextField("Enter name", text: self.$userInput).focused(self.$textFieldIsFocused)
                .onChange(of: self.textFieldIsFocused)
                {
                    print("textFieldIsFocused")
                }
            }
        }
    }
}

When the TextField is activated and the keyboard appears, the .onChange of is not occurring and "textFieldIsFocused" is not being printed to the console. However, when I move the code for the TextField out of the.sheet and onto the View itself, it works perfectly fine. How can I get this FocusState property to work when the TextField is on the .sheet?


Solution

  • It works when you factor out the sheet content into a separate view:

    struct TestViewSheet: View {
        @Binding var userInput: String
        @FocusState private var textFieldIsFocused: Bool
    
        var body: some View {
            HStack {
                Text("Name:")
                TextField("Enter name", text: $userInput)
                    .focused($textFieldIsFocused)
                    .onChange(of: textFieldIsFocused) {
                        print("textFieldIsFocused")
                    }
            }
        }
    }
    
    struct TestView: View {
        @State private var sheetIsPresented: Bool = false
        @State private var userInput: String = ""
    
        var body: some View {
            Button("Hello") {
                sheetIsPresented = true
            }
            .buttonStyle(.borderedProminent)
            .sheet(isPresented: $sheetIsPresented) {
                TestViewSheet(userInput: $userInput)
            }
        }
    }