繁体   English   中英

带有 CustomView 的 onTapGesture 不刷新子视图

[英]onTapGesture with CustomView not Refreshing child view

我在使用自定义视图处理“onTapGesture”修饰符时遇到了一些问题。

struct CheckView: View {
    @State var isChecked: Bool = false
    
    var title: String
    var unitPrice: String
    
    var body: some View {
       Button(action: toggle){
           HStack{
               Image(systemName: isChecked ? "checkmark.square": "square")
               HStack {
                   Text(title)
                   Spacer()
                   Text("- $\(unitPrice)")
                       .frame(width: 65, alignment: .leading)
               }
               .foregroundColor(.black)
               Spacer()
           }
       }
    }
    
    func toggle() {
        isChecked = !isChecked
    }

上面的自定义视图是一个复选框行视图。 当您单击该行时,它基本上只是将 sf-symbol 从选中框切换为空框。

在创建它的父视图中,我从 Realm 数据库中提取数据以填充列表视图中的项目。

@ObservedResults(Item.self) var items
    
@StateObject private var viewModel = ViewModel()

List {
    ForEach(items) { item in
        CheckView(title: item.itemDescription, unitPrice: String(format: "%.2f", item.unitPrice))
            .onTapGesture {
                viewModel.updateSelectedItems(item: item)
            }
    }
}

//ViewModel Function
@Published var selectedItems: [Item] = []
        
func updateSelectedItems(item: Item) {
    if (selectedItems.contains(item)) {
        selectedItems.removeAll(where: { $0 == item })
    }
    else {
        selectedItems.append(item)
    }
}

我想要做的是使用点击手势在 viewmodel 中调用 function,以便我可以获得已点击项目的运行列表。 我可以确认 ViewModel 代码正常工作(我有一个调试警报显示 Published 数组正在更新)但是发生的事情是 CheckView 没有刷新,就像在点击一行时,复选框 sf-symbol没有按应有的方式切换。 看起来它什么都不做。

我怀疑这是 CheckView 上的 Button 和父视图上的 onTapGesture 之间的某种冲突,但我不确定。

如果您有任何想法,将不胜感激。

提前致谢。

您可以尝试以下方法将ItemViewModel传递给CheckView

 struct CheckView: View {
     @EnvironmentObject var viewModel: ViewModel
     
    @State var item: Item
    @State var isChecked: Bool = false
    
    var body: some View {
        Button(action: {
            viewModel.updateSelectedItems(item: item)
            isChecked.toggle()
        }){
            HStack{
                Image(systemName: isChecked ? "checkmark.square": "square")
                HStack {
                    Text(item.itemDescription)
                    Spacer()
                    Text("- $\(String(format: "%.2f", item.unitPrice))")
                        .frame(width: 65, alignment: .leading)
                }
                .foregroundColor(.black)
                Spacer()
            }
        }
        .onAppear {
            isChecked = viewModel.selectedItems.contains(where: {$0.id == item.id})
        }
    }
}

并像这样使用它,没有onTapGesture

List {
    ForEach(items) { item in
        CheckView(item: item)
    }
}.environmentObject(viewModel)  // <-- here
    

根据上面的答案,如果您将viewModel传递给CheckView ,您是否可以不检查该项目是否在selectedItems数组中?

struct CheckView: View {
  @EnvironmentObject var viewModel: ViewModel
 
  @State var item: Item
  var isSelected: Bool {
    viewModel.selectedItems.containts(item)
  }

  var body: some View {
    Button(action: {
      viewModel.updateSelectedItems(item: item)
    }) {
      HStack {
        Image(systemName: isSelected ? "checkmark.square": "square")
          HStack {
            Text(item.itemDescription)
            Spacer()
            Text("- $\(String(format: "%.2f", item.unitPrice))")
              .frame(width: 65, alignment: .leading)
            }
            .foregroundColor(.black)
            Spacer()
          }
        }
      }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM