Home > front end >  SwiftUI - MacOS - TextField within Alert not receiving focus
SwiftUI - MacOS - TextField within Alert not receiving focus

Time:12-17

I've added a TextField within an Alert in MacOS. However, the TextField doesn't receive focus, when the alert shows. Here's the code I've tested with. Is this even possible? If this is a bug, then please suggest other workarounds.

import SwiftUI

struct ContentView: View {
    @State private var presented = false
    @State private var username = ""
    @FocusState private var focused: Bool
    
    var body: some View {
        VStack {
            Button(action: {
                focused = true
                presented = true
            }, label: {
                Text("Click to show Alert")
            })
        }
        .alert("", isPresented: $presented, actions: {
            VStack {
                TextField("User name (email address)", text: $username)
                    .focusable()
                    .focused($focused)
                Button(action: {}, label: { Text("OK") })
            }
            .onAppear() {
                // Try setting focus with a delay.
                DispatchQueue.main.asyncAfter(deadline: .now()   0.1, execute: {
                    focused = true
                })
            }
        }, message: {
            Text("The textField in this alert doesn't get the focus. Therefore, a manual click is needed to set focus and start typing.")
        })
    }
}

CodePudding user response:

I can confirm that focus doesn't work inside Alert. A possible workaround is using a custom Sheet:

struct ContentView: View {
    @State private var presented = false
    @State private var username = ""
    @FocusState private var focused: Bool

    var body: some View {
        VStack {
            Button(action: {
                presented = true
                focused = true
            }, label: {
                Text("Click to show Sheet")
            })
        }
        
        .sheet(isPresented: $presented, content: {
            
            VStack {
                // App Icon placeholder
                RoundedRectangle(cornerRadius: 8)
                    .fill(.secondary)
                    .frame(width: 48, height: 48)
                    .padding(12)
                
                Text("The textField in this alert doesn't get the focus. Therefore, a manual click is needed to set focus and start typing.")
                    .font(.caption)
                    .multilineTextAlignment(.center)

                TextField("User name (email address)", text: $username)
                    .focused($focused)
                    .padding(.vertical)
                
                Button(action: {
                    presented = false
                }, label: {
                    Text("OK")
                        .frame(maxWidth: .infinity)
                })
                .buttonStyle(.borderedProminent)
            }
            .padding()
            .frame(width: 260)
        })
    }
}
  • Related