Search code examples
listbuttonswiftuinavigationview

How to select checkbox button and NavigationLink to another view independently in SwiftUI List row


I hope to make a list just like to-do list, the cell has a checkbox and Text. And I want when list cell selected, the view could be translate to detailView. Meanwhile I also could select the checkbox, but don't trigger the view translate to the detailView.

I removed the List{}, the code run ok, but the List property and method can't use any more. So I plan to code a customer list view. But I don't think it will be the good method. So if I still can't find a good way to make it, I may implement in this way at last.

NavigationView {
     VStack {   
        List {
                 ForEach(todayDietModel.todayDietItems) { item in
                     NavigationLink(destination: DietItemDetailView()) {
                            TodayDietRow(todayDietItem: item)
                                .animation(.spring())
                        }
                    }
                }

            }
            .frame(width: 352, height: 400)
            .background(Color.white)
            .cornerRadius(16)

}


struct TodayDietRow: View {
   @State var isFinished: Bool = false

    var body: some View {
        HStack(spacing: 20.0) {
            Button(action: {self.isFinished.toggle()}) {
                if self.isFinished {
                    Image("icon_checked_s001")
                        .resizable()
                        .renderingMode(.original)
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 24, height: 24)
                } else {
                    Image("icon_unchecked_s001")
                        .resizable()
                        .frame(width: 24, height: 24)
                }

            }
            .padding(.leading, 10)


            Text("DietName")
                .font(.system(size:13))
                .fontWeight(.medium)
                .foregroundColor(Color.black)   

        }
        .frame(width: 327, height: 48)


    }
}



Solution

  • This works quite well with a gesture on the checkbox image. Two Buttons didn't work since every tap went to both buttons.

    struct TodayTodoView2: View {
        @ObservedObject var todayDietModel = TodayDietModel()
    
        func image(for state: Bool) -> Image {
            return state ? Image(systemName: "checkmark.circle") : Image(systemName: "circle")
        }
    
        var body: some View {
            NavigationView {
                VStack {
                    List {
                        ForEach($todayDietModel.todayDietItems) { (item: Binding<TodayDietItem>) in
                            HStack{
                                self.image(for: item.value.isFinished).onTapGesture {
                                    item.value.isFinished.toggle()
                                }
                                NavigationLink(destination: DietItemDetailView2(item: item)) {
                                    Text("DietNamee \(item.value.dietName)")
                                        .font(.system(size:13))
                                        .fontWeight(.medium)
                                        .foregroundColor(Color.black)
                                }
                            }
                        }
                    }
                    .background(Color.white)
                }
            }
        }
    }