How to add button in custom View (ListRowView) without providing prior functionality, in Swift UI?

Viewed 86

Code below is working perfectly but i have an issue, i don't want to provide functionality here, i just want to add button (dropDownButton) and provide the functionality when using this custom view.

struct DrawerItemListRowView: View {
    
@State var iconName: Icon
@State var text: String
@State var dropDownButton = Button(action: {}) {
    Image(icon: .drawer)
}


var body: some View {
    
    HStack(alignment: .center, spacing: 15) {
        
        Image(icon: iconName)

        Text(text)
            .foregroundColor(.customLightBlack)
            .font(.custom(ubuntu: .regular, style: .title2))
        
        Spacer()
        
        dropDownButton
            .frame(width: 24, height: 24, alignment: .trailing)
    }
    .padding()
    .listRowSeparator(.hidden)
    .listRowBackground(Color.customBackground)
    .background(Color.clear)
}
}

struct DrawerItemListRowView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            DrawerItemListRowView(iconName: .mainCategory, text: "Shop by category")
            DrawerItemListRowView(iconName: .paymentMethod, text: "Payment Methods")
        }
        .previewLayout(.sizeThatFits)
        .background(.white)
    } }
1 Answers

You need to pass the action, not the button, as of type ()->Void.

Check out this example:

struct DrawerItemListRowView: View {
    let iconName: String
    let text: String
    let action: ()->Void   // Pass the action, not the button

    var body: some View {
        
        HStack(alignment: .center, spacing: 15) {
            
            Image(systemName: iconName)

            Text(text)
                .foregroundColor(.gray)
            
            Spacer()
            
            Button {
                action()    // Call the action
            } label: {
                Text(text)
                    .fixedSize()
            }
                .frame(width: 24, height: 24, alignment: .trailing)
        }
        .padding()
        .listRowSeparator(.hidden)
        .listRowBackground(Color.yellow)
        .background(Color.clear)
    }
}

struct Example: View {
    
    var body: some View {
        VStack {
            DrawerItemListRowView(iconName: "house", text: "Shop by category") {
                print("Bought")
            }
            DrawerItemListRowView(iconName: "minus", text: "Payment Methods") {
                print("Paid")
            }
        }
        .previewLayout(.sizeThatFits)
        .background(.white)
    }
}
Related