Home > database >  iOS button and navigationLink next to each other in List
iOS button and navigationLink next to each other in List

Time:09-15

I have a List, each element has its own HStack that contains Button and NavigationLink to the next view but both (checkbox button and navigation link) is activated wherever I click on single HStack element.

That means icon on the button changes when I click on the element but application also loads the next view. The same happens when I want to go to the next view by simply clicking on the NavigationLink. Can you help me separate this two functionalities (checkbox Button and NavigationLink)?

struct ContentView: View {
    @ObservedObject var spendingList: SpendingList
    
    var body: some View {
        NavigationView {
            List {
                ForEach($spendingList.spendings) { $spending in
                    HStack{
                        Button(action: {
                            spending.Bought = !spending.Bought
                        }, label: {
                            if spending.Bought == false {
                                Image(systemName: "square")
                                    .foregroundColor(.accentColor)
                            } else {
                                Image(systemName: "checkmark.square")
                                    .foregroundColor(.accentColor)
                            }
                        })
                        
                        NavigationLink(destination: DetailView(spending: $spending)
                            .navigationTitle(Text(spending.Name)),
                                       label: {
                            Text(spending.Name).frame(maxWidth: .infinity, alignment: .leading)

                            if spending.Price != 0 {
                                Text(String(spending.Price)).frame(maxWidth: .infinity, alignment: .trailing)
                            } else {
                                Text("empty").foregroundColor(.gray)
                            }
                        })
                    }
                }
                .navigationTitle(Text("Spending Priority"))
            }
        }
    }
}

CodePudding user response:

The default Style of Button & NavigationLink makes the whole row click as one. However, using PlainButtonStyle() fixes the issue by making the button clickable & not the cell:

.buttonStyle(.plain)//to your button & NavigationLink

CodePudding user response:

Unfortunately, the parent-view list item becomes the Navigation link. So the button press will never be recorded.

In iOS 16 you can solve this by replacing the NavigationLink with a Button and pushing an item onto the navigation stack with the Button.

Documentation: https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types

Something like this, for example:

struct ContentView: View {

    @State var path: [View] = []
    
    var body: some View {
        NavigationStack(path: $path) {
            List {
                ForEach($spendingList.spendings) { $spending in
                    HStack {
                        Button(action: {
                            spending.Bought = !spending.Bought
                        }, label: {
                            Image(...)
                        })
                        
                        Button(action: {
                            path.append(DetailView(spending: $spending))
                        }, label: {
                            Text(...)
                        })
                            Text(spending.Name)
                        })
                    }
                }
            }
            .navigationTitle(Text("Spending Priority"))
            .navigationDestination(for: View.self) { view in
                view
            }
        }
    }
}
  • Related