微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单击列表项上的按钮与整个项重叠

如何解决单击列表项上的按钮与整个项重叠

我创建了一个卡片列表,每张卡片都有一个按钮来执行一个操作。 但是当我进行测试时,我注意到我可以点击卡片所在的位置,也可以执行按钮的操作。这是我在 switf 上的第一个应用程序,所以我没有任何经验。 有人可以帮忙吗?

这是项目视图已编辑

typealias changeStatusAlias = (OrderDTO,String,String?) -> Void

struct OrderItem: Identifiable {
    let id = UUID()
    let order: OrderDTO
}
struct ItemOrderRiderView: View {
    
    private let item: OrderItem
    @State private var showMethodPicker = false
    private let changeState: changeStatusAlias
    private let showDialogPayment: (OrderDTO)-> Void
    private let orderValue: String?
    @Observedobject var locationManager = LocationManager()

    init(item: OrderItem,changeState: @escaping changeStatusAlias,showDialogPayment: @escaping (OrderDTO)-> Void) {
        let formatter = NumberFormatter()
        self.item = item
            formatter.numberStyle = NumberFormatter.Style.currencyAccounting
            formatter.locale = Locale(identifier: "DE")
            formatter.currencyCode = "eur"
        self.changeState = changeState
        self.showDialogPayment = showDialogPayment
        orderValue = formatter.string(from: NSNumber(value: item.order.value))
    }
    
    var body: some View {
        ZStack {
            
            vstack {
                HStack{
                    Text(item.order.orderNumber)
                        .fontWeight(.bold)
                        .padding(.leading,/*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/)
                    
                    Spacer()
                    Text(item.order.subStateName)
                        .padding(.trailing,10)
                }.padding(.top,5)
                
                HStack{
                    Text(item.order.commercialName)
                        .fontWeight(.bold)
                        .padding(.leading,/*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/)
                    
                    Spacer()
                    Text(item.order.deliveryHour)
                        .padding(.trailing,5)
                
                Text(item.order.user)
                    .padding(.leading,10)
                    .padding(.top,10)
                    .frame(maxWidth: .infinity,alignment: .leading)
                
                Text(item.order.stateName)
                    .padding(.leading,1)
                    .frame(maxWidth: .infinity,alignment: .leading)
                
                Text(orderValue!)
                    .padding(.leading,alignment: .leading)
                
                HStack {
                    Image("pin_grey")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 30,height: 30,alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                    Text("\(item.order.routedistance) km")
                        .foregroundColor(Color(hue: 1.0,saturation: 0.045,brightness: 0.397))
                        .font(.system(size: 14))
                        
                        
                    
                    Spacer()
                    
                    Image("watch_grey")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 30,alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                    Text("\(item.order.routeTime) min")
                        .foregroundColor(Color(hue: 1.0,brightness: 0.397))
                        .font(.system(size: 14))
                    
                    Button(action: {
                        self.locationManager.locationString = item.order.completeAddress ?? ""
                        self.locationManager.openMapWithAddress()
                    },label: {
                        Image("map_loc_red")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 30,alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                            .padding(.leading,30)
                    })
                
                    Spacer()
                    
                    Button(action: {
                        
                    },label: {
                        Image("pin_quick_red")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 30,20)
                    })
                    
                    Spacer()
                    
                    Image("info_black")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 30,alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                        .padding(.leading,20)
                }.padding(.bottom,10)
                
                Button(
                    action: {
                        
                    switch item.order.riderActions.getRequestValueState(){
                    case "delivered":
                        if(item.order.orderState == "quickdelivery_cash") {
                            showDialogPayment(item.order)
                        } else {
                            changeState(
                                item.order,item.order.riderActions.getRequestValueState(),SubStateAction.Companion().SUB_STATE_FIELD,nil
                            )
                        }
                        break
                    default:
                        changeState(
                            item.order,nil
                        )
                        break
                    }
                }) {
                    Text(item.order.riderActions.getTitle().localized())
                }
                .frame(width: 300,height: 40,alignment: .bottom)
                    
            }.cornerRadius(10)
            .overlay(
                RoundedRectangle(cornerRadius: 10)
                    .stroke(Color(.sRGB,red: 150/255,green: 150/255,blue: 150/255,opacity: 0.1),linewidth: 1)
            )
            .padding([.top,.horizontal])
            .alert(isPresented: $locationManager.invalid) {
                Alert(title: Text("Important message"),message: Text("Enter a valid address"),dismissButton: .default(Text("OK"),action:{
                                    locationManager.invalid = false
                                    locationManager.locationString = ""
                                }))
                            }
        }
    }
}

struct ItemOrderRiderView_Previews: PreviewProvider {
    static var previews: some View {
        ItemOrderRiderView(
            item: OrderItem(order: mockedOrder),changeState: {(mock1,mock2,mock3,mock4) in},showDialogPayment: {mock1 in}
        )
            .previewLayout(.fixed(width: 400,height: 400))
    }
}


private let mockedOrder = OrderDTO(
    id: 0001,orderNumber: "0001",user: "Teste Da Silva",kitchenStateName: "ready",stateName: "quickdelivery cash",subStateName: "in progress",deliveryHour: "10:00 - 11:55",value: 100,type: LoginLabel.Companion().loginButton,action: [ResourcesstringDesc](),commercialName: "Restaurante teste",riderActions: SubStateAction.delivered,routedistance: "100",routeTime: "5",completeAddress: "rua teste 12",googleAddress: "rua teste 12",userPhone: "999999999",restaurantLocation: Localization(latitude:0,longitude:0),riderId: 2312,orderState: "quickdelivery_cash",deliveryLocation: Localization(latitude: 0,longitude: 0),deliveryStateString: "delivery_in_progress",commercialPremiseId: 12,riderName: "Joao da Silva"
    )

更新: 我实现了其他按钮操作,而且我也遇到了同样的问题,现在当我点击卡片时,它会执行所有按钮点击动作,所以当我添加一个新按钮时,它也会在我点击卡片时执行。

这就是我实施列表的方式:

struct DeliveryManagerView: View {
    @Observedobject private var viewmodel: Orderviewmodel
    @Observedobject var profileviewmodel: Profileviewmodel
    init(repository: OrderRepository,profileviewmodel: Profileviewmodel) {
        self.viewmodel = Orderviewmodel(repository: repository)
        self.profileviewmodel = profileviewmodel
    }
    
    let timer = Timer.publish(every: 30,on: .main,in: .common).autoconnect()
    @State private var showPaymentAlert = false

    @State private var order:OrderDTO? = nil
    
    var body: some View {
        
        GeometryReader { proxy in
            ZStack(alignment: .bottom) {
                List(viewmodel.ordersItems) { item in
                    ItemOrderRiderView(
                        item: item,changeState: { (order,request,stateField,paymentMethod) in
                                        viewmodel.changeOrderState(
                                            orderDTO: order,request: request,stateField: stateField,paymentMethod: paymentMethod
                                                )
                                        },showDialogPayment: {order in
                            self.order = order
                            self.showPaymentAlert = true
                        }
                    )
                }.onAppear(perform: {
                    manageConfigRequests()
                })
                .padding(.bottom,proxy.safeAreaInsets.top)
                
                if(viewmodel.loading){
                    ActivityIndicator()
                        .frame(width: 50,height: 50,alignment: .center)
                        .foregroundColor(.orange)
                }
            }.padding(.bottom,proxy.safeAreaInsets.top)
            .customDialog(isShowing: $showPaymentAlert,dialogContent: {
                PaymentMethoDalert { method in
                                    viewmodel.changeOrderState(
                                        orderDTO: self.order!,request: self.order!.riderActions.getRequestValueState(),stateField: SubStateAction.Companion().SUB_STATE_FIELD,paymentMethod: method
                                    )
                    self.showPaymentAlert = false
                }
            })
        }.onReceive(timer,perform: { _ in
            viewmodel.getorders(profile: profileviewmodel.defaultProfile!)
        })
    }
    
    
    private func manageConfigRequests() {
        if(profileviewmodel.defaultProfile != nil) {
            viewmodel.getorders(profile: profileviewmodel.defaultProfile!)
        } else {
            profileviewmodel.getProfile()
        }
        if(viewmodel.changedState) {
            viewmodel.getorders(profile: profileviewmodel.defaultProfile!)
        }
    }
}

解决方法

看起来 List() 有这个限制,整个项目都可以点击。 所以我解决了将 List 更改为 ScrollView() 并使用 ForEach() 的问题:

 ScrollView {
                    ForEach(viewModel.ordersItems,id: \.self) {
                        item in
                        ItemOrderRiderView(
                            item: item,changeState: { (order,request,stateField,paymentMethod) in
                                viewModel.changeOrderState(
                                    orderDTO: order,request: request,stateField: stateField,paymentMethod: paymentMethod
                                )
                            },showDialogPayment: {order in
                                self.order = order
                                self.showPaymentAlert = true
                            }
                        )
                    }
                }.onAppear(perform: {
                    manageConfigRequests()
                })
                .padding(.bottom,proxy.safeAreaInsets.top)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。