2

I have a ScrollView with a LazyVStack which holds n subviews. Each subview has a button which will present a confirmation dialog, the confirmation dialog is created inside the child.

the confirmation dialog for some reason doesn't work after seeing 3 (more or less) subviews, you could press the button many times but won't immediately show the dialog, if you wait around while scrolling, suddenly every dialog will popup one after another.

video testing

Code for testing:

struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 50) {
                ForEach(0...100, id: \.self) { _ in
                    SubView()
                }
            }
        }
        .padding()
    }
}


struct SubView: View {
    
    @State var flag = false
    
    var body: some View {
        ZStack(alignment: .bottom) {
            RoundedRectangle(cornerRadius: 30)
                .frame(height: 500)
                .foregroundColor(.gray)
                .overlay {
                    Button("Press me") {
                        flag.toggle()
                    }
                    .confirmationDialog("", isPresented: $flag, actions: {
                        Button(role: .none) {
                           print("option 1")
                        } label: {
                            Text("option 1")
                        }
 
                        Button(role: .cancel) {
                            flag = false
                        } label: {
                            Text("cancel")
                        }
                    })
                }
        }
    }
}
Javier Heisecke
  • 1,162
  • 1
  • 11
  • 28
  • Agreed, LazyVStack doesn't work. Just curious could you use a List instead? Also please file a feedback using Feedback Assistant – user1046037 Nov 09 '22 at 15:23
  • for this example I could use a List, but for the app I'm building we're using a ScrollView – Javier Heisecke Nov 09 '22 at 15:28
  • did you find a way around this? can't believe it's still not fixed... – kironet Mar 02 '23 at 04:45
  • 1
    @kironet the answer in this question is a way around, it's not the answer I was looking for but it works. I added a closure on my child view following the delegate pattern, so my parent has the responsibility to show the confirmationDialog. Hope that helps – Javier Heisecke Mar 03 '23 at 12:57

1 Answers1

1

Approach

  • Move the confirmationDialog outside the LazyVStack

Code

struct ContentView: View {
    @State private var flag = false
    
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 50) {
                ForEach(0...100, id: \.self) { _ in
                    SubView(flag: $flag)
                }
            }
            .confirmationDialog("", isPresented: $flag) {
                Button(role: .none) {
                    print("option 1")
                } label: {
                    Text("option 1")
                }
                
                Button(role: .cancel) {
                    flag = false
                } label: {
                    Text("cancel")
                }
            }
        }
        .padding()
    }
}

struct SubView: View {
    
    @Binding var flag: Bool
    
    var body: some View {
        ZStack(alignment: .bottom) {
            RoundedRectangle(cornerRadius: 30)
                .frame(height: 500)
                .foregroundColor(.gray)
                .overlay {
                    Button("Press me") {
                        flag.toggle()
                    }
                }
        }
    }
}
user1046037
  • 16,755
  • 12
  • 92
  • 138