emehex
emehex

Reputation: 10528

SwiftUI .focused() View Modifier not working .onAppear

I'm trying to get the new iOS 15.0 .focused() View Modifier to execute when a SwiftUI View appears:

import SwiftUI

struct MainView: View {
    @State var subViewIsDisplayed = false
    var body: some View {
        VStack {
            Spacer()
            Button(action: { subViewIsDisplayed.toggle() }) {
                Text("Trigger SubView")
            }
            Spacer()
        }
        .fullScreenCover(isPresented: $subViewIsDisplayed) {
            SubView()
        }
    }
}

struct SubView: View {
    @Environment(\.dismiss) var dismiss
    @FocusState private var isFocused: Bool
    @State var text = ""
    
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Button(action: { dismiss() }) {
                    Image(systemName: "xmark")
                }
            }
            Spacer()
            TextField("Please autofocus :(", text: $text)
                .focused($isFocused)
            Spacer()
        }
        .onAppear {
            self.isFocused = true
        }
    }
}

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        MainView()
    }
}

On my physical device, triggering "SubView" doesn't bring up the keyboard (as I would expect from .focused). What am I doing wrong?

Upvotes: 6

Views: 1646

Answers (3)

Zhoumin Lu
Zhoumin Lu

Reputation: 52

This worked for me

.onAppear {
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.7){
        isFocused = true
    } //Delayed execution of 0.7s
}

Upvotes: 4

Ivan Kvyatkovskiy
Ivan Kvyatkovskiy

Reputation: 727

        .onAppear {
            DispatchQueue.main.async {
                isFocused = true
            }
        }

DispatchQueue.main.async, as always will do the trick

enter image description here

Upvotes: 10

Rob N
Rob N

Reputation: 16399

Looks like another SwiftUI bug to me. Here's a workaround.

All my changes to your example code are in the onAppear closure.

I'm getting it to work at i=7 on both simulator and device.

struct SubView: View {
    @Environment(\.dismiss) var dismiss
    @FocusState private var isFocused: Bool
    @State var text = ""
    
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Button(action: { dismiss() }) {
                    Image(systemName: "xmark")
                }
            }
            Spacer()
            TextField("Please autofocus :(", text: $text)
                .focused($isFocused)
            Spacer()
        }
        .onAppear {
            Task {
                for i in 1...20 {
                    isFocused = true
                    if isFocused {
                        print("The set finally stuck. i=\(i)")
                        break
                    }
                    await Task.sleep(100_000_000)
                }
            }
        }
    }
}

Upvotes: 0

Related Questions