当我试图从一个使用带有确认按钮的闭包的视图中发送一个带有PassthroughSubject var的事件信号时,我遇到了一些问题。
为了在上下文中,我构建了两个视图:SavedRewardsView和WishListItemCard。WishListItemCard使用PassthroughSubject发出事件,SavedRewardsView使用.onReceive属性接收事件。
到目前为止一切顺利,我已经设法发出和捕获WishListItemCard上的事件,实现了一个计数器并更新WishListItemCard中的UI,并将事件发送到SavedRewardsView以更新它的UI。
- 在WishListItemCard上发送事件:*
@State var redeemCount = 0
let didChange = PassthroughSubject<WishlistItemCounter, Never>()
VStack {
...
}
.onChange(of: self.redeemCount) { newCount in
self.pointsCost = newCount * (self.rewardData.points ?? 0)
let wic = WishlistItemCounter(rewardId: self.rewardData.id ?? 0, quantity: newCount, total: self.pointsCost)
self.didChange.send(wic)
}
- 在SavedRewardsView上捕获事件:*
let wishlistItemCard = WishlistItemCard()
wishlistItemCard.onReceive(wishlistItemCard.didChange) { newWishlistItemCounter in
print("wishlistItemCard.didChange")
}
问题在另一个事件上,该事件也需要从WishListItemCard发送。预期的功能是用户应该能够基于确认消息从愿望列表中删除项目,并且由于这是从SavedRewardsView调用的视图,因此需要重新加载数据,以便删除的项目不再出现在列表中。因此,在删除按钮的操作中,有一个自定义警报的调用,该警报需要一个标题和2个操作:一个用于确认动作,另一个用于取消动作。我在confirm操作中发送事件:
- 在SavedRewardsView上发送事件:*
let didDeleteReward = PassthroughSubject<Bool, Never>()
Button(action: {
let confirmDeleteButton = CustomAlertButton(title: "Confirm", action: {
self.myAppManager.hideAlert()
self.didDeleteReward.send(true)
}
let cancelButton = CustomAlertButton(title: "Cancel", action: {
self.myAppManager.hideAlert()
}
self.myAppManager.showAlert(
message: "Delete item?",
dismissButton: cancelDeleteButton,
primaryButton: confirmDeleteButton
)
},
label: {
Image("TrashIcon")
.resizable()
.scaledToFit()
.frame(width: 25, height: 25)
})
并尝试在SavedRewardsView上接收事件,但此处未捕获该事件:
let wishlistItemCard = WishlistItemCard()
wishlistItemCard
.onReceive(wishlistItemCard.didChange) { newWishlistItemCounter in
print("wishlistItemCard.didDeleteReward")
Task {
await self.reloadData()
}
}
以下是我尝试过的:
1.使用@State变量并将其附加到.onReceive并发送事件,但SavedRewardsView上未捕获该事件。
1.使用CurrentValueSubject,但值本身会一直更新,成为一个无限的更新循环。
1.将 self.didDeleteReward.send(true) 直接放置在按钮的操作上,没有确认消息,事件将在SavedRewardsView上捕获,但它不是预期的行为,因为它需要确认。
你们能帮帮我吗,我真的没办法了。
- 注意:myAppManager var是一个ObservableObject,它是我的应用程序的真实来源,并且从第一个扩展App的视图中分层传递到具有.environmentObject的视图。
1条答案
按热度按时间juud5qan1#
SwiftUI已经内置了passthrough subjects(尽管它被称为依赖跟踪或更改检测),所以你不需要自己重新创建它,只需执行以下操作:
将
body
看作是View
中声明的所有let
和@State var
的didChange
函数。