带有 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 符号从选中框切换为空框。
在我创建它的父视图中,我从 Realm DB 中提取以填充列表视图中的项目。
@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: { [=11=] == item })
}
else {
selectedItems.append(item)
}
}
我想做的是使用点击手势调用视图模型中的函数,这样我就可以得到一个 运行 列表,其中包含已点击的项目。我可以确认 ViewModel 代码正常工作(我有一个调试警报,显示 Published 数组正在更新)但是发生的事情是 CheckView 没有刷新,就像在点击一行时,复选框 sf-symbol没有按应有的方式切换。好像什么都没做。
我怀疑这是 CheckView 上的 Button 和父视图上的 onTapGesture 之间的某种冲突,但我不确定。
如果您有任何想法,我们将不胜感激。
提前致谢。
您可以尝试以下方法将 Item
和 ViewModel
传递给 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: {[=10=].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()
}
}
}
}
我在使用自定义视图处理“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 符号从选中框切换为空框。
在我创建它的父视图中,我从 Realm DB 中提取以填充列表视图中的项目。
@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: { [=11=] == item })
}
else {
selectedItems.append(item)
}
}
我想做的是使用点击手势调用视图模型中的函数,这样我就可以得到一个 运行 列表,其中包含已点击的项目。我可以确认 ViewModel 代码正常工作(我有一个调试警报,显示 Published 数组正在更新)但是发生的事情是 CheckView 没有刷新,就像在点击一行时,复选框 sf-symbol没有按应有的方式切换。好像什么都没做。
我怀疑这是 CheckView 上的 Button 和父视图上的 onTapGesture 之间的某种冲突,但我不确定。
如果您有任何想法,我们将不胜感激。
提前致谢。
您可以尝试以下方法将 Item
和 ViewModel
传递给 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: {[=10=].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()
}
}
}
}