Home > Net >  How to add images to buttons inside `confirmationDialog`
How to add images to buttons inside `confirmationDialog`

Time:07-14

I'm building my first SwiftUI app and I've run into a blocker. When a user long-presses one of my cells, I want to show a confirmationdialog with custom buttons.

Here's the code:

.confirmationDialog("", isPresented: $showLongPressMenu) {
    Button {
        //
    } label: {
        HStack {
            Image(systemName: "checkmark.circle")
            Text("Add completion")
        }
    }
    Button {
        //
    } label: {
        HStack {
            Image(systemName: "note.text.badge.plus")
            Text("Add Note")
        }
    }
    Button("Cancel", role: .cancel) {}
}

This is sort-of working, here's the result:

enter image description here

But what I'm trying to achieve is something like this:

enter image description here

Any pointers would be amazing, thank you.

CodePudding user response:

Here's a quick pure SwiftUI custom Dialog I wrote using resultBuilder avoiding the Divider approach:

Package URL: enter image description here

struct ContentView: View {
    
    @State private var showConfirmationDialog = false
    @State private var showModifierDialog = false
    
    var body: some View {
        VStack {
            Button("Show Dialog") { showConfirmationDialog = true }
            Button("Show ViewMod Dialog") {
                withAnimation {
                    showModifierDialog = true
                }
            }
            .padding()
        }
        .padding()
        
        // standard confirmationDialog
        .confirmationDialog("Test", isPresented: $showConfirmationDialog) {
            Button { } label: {
                Label("Add completion", systemImage: "checkmark.circle")
            }
            Button { } label: {
                Label("Add Note", systemImage: "note.text.badge.plus")
            }
            Button("Cancel", role: .cancel) {}
        }
        
        // custom confirmationDialog with Icons, Cancel added automatically
        .customConfirmDialog(isPresented: $showModifierDialog) {
            Button {
                // action
                showModifierDialog = false
            } label: {
                Label("Add completion", systemImage: "checkmark.circle")
            }
            Divider() // unfortunately this is still necessary
            Button {
                // action
                showModifierDialog = false
            } label: {
                Label("Add Note", systemImage: "note.text.badge.plus")
            }
        }
    }
}


// *** Custom ConfirmDialog Modifier and View extension

extension View {
    func customConfirmDialog<A: View>(isPresented: Binding<Bool>, @ViewBuilder actions: @escaping () -> A) -> some View {
        return self.modifier(MyCustomModifier(isPresented: isPresented, actions: actions))
    }
}

struct MyCustomModifier<A>: ViewModifier where A: View {
    
    @Binding var isPresented: Bool
    @ViewBuilder let actions: () -> A
    
    func body(content: Content) -> some View {
        ZStack {
            content
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            
            ZStack(alignment: .bottom) {
                if isPresented {
                    Color.primary.opacity(0.2)
                        .ignoresSafeArea()
                        .onTapGesture {
                                isPresented = false
                        }
                        .transition(.opacity)
                }
                
                if isPresented {
                    VStack {
                        GroupBox {
                            actions()
                                .frame(maxWidth: .infinity, alignment: .leading)
                        }
                        
                        GroupBox {
                            Button("Cancel", role: .cancel) {
                                    isPresented = false
                            }
                            .bold()
                            .frame(maxWidth: .infinity, alignment: .center)
                        }
                    }
                    .font(.title3)
                    .padding(8)
                    .transition(.move(edge: .bottom))
                }
            }
        }
        .animation(.easeInOut, value: isPresented)
   }
}
  • Related