swiftui - 在继续之前等待 actionSheet 结果?
问题描述
我在 a 中有一个按钮.contextMenu
(即:标记为已付款)
它做的第一件事是在 actionSheet 上切换以选择付款方式。紧接着是一些代码,通过 EventKit 向用户日历添加条目。
我的问题是我希望 actionSheet在 EventKit 代码执行之前返回一个结果。
你如何让它等待?
特性:
@State private var showPaymentSheet = false
@State private var paymentType = ""
var actionSheet: ActionSheet {
ActionSheet(title: Text("Payment Method"), buttons: [
.default(Text(" Cash")) { paymentType = " Cash" },
.default(Text(" Bank Transfer")) { paymentType = " Bank" },
.default(Text("️ PayPal")) { paymentType = "️ PayPal" },
.default(Text(" Cheque")) { paymentType = " Cheque" },
.cancel()
])
}
身体:
.contextMenu {
Button(action: {
**// Run This ActionSheet FIRST and get result of \(paymentType) **
self.showPaymentSheet.toggle()
**// ONLY then continue with below **
let thisDay = self.selectDate.selectedDate
let eventStore = EventsRepository.shared.eventStore
let payment = EKEvent(eventStore: eventStore)
payment.calendar = event.calendar
payment.startDate = event.startDate
payment.endDate = event.endDate
payment.title = "\(event.title!)"
payment.notes = "\(event.notes!)\nPaid: \(Date().dateType(dateFormat: "EEE MMM dd yyyy @ HH:mm b " )) by \(paymentType)"
payment.location = "\(event.location!)"
do {
try eventStore.save(payment, span: .thisEvent)//i - Save Updated (event)
try EventsRepository.shared.eventStore.remove(event, span: .thisEvent)
EventsRepository.shared.loadAndUpdateEvents(selectedDate: thisDay)
} catch {
print("Failled to cancel event")
}
NotificationCenter.default.post(name: .eventsDidChange, object: nil)
}){
HStack {
Text("Mark as Paid")
.font(Font.custom("ChalkboardSE-Bold", size: 32))
Image("payment")
.renderingMode(.original)
}
}.actionSheet(isPresented: $showPaymentSheet, content: {
self.actionSheet})
}
解决方案
您可以使用onReceive
.
这是一个简单的演示:
struct ContentView: View {
@State private var showPaymentSheet = false
@State private var paymentType = ""
var body: some View {
Button("Choose payment") {
self.showPaymentSheet.toggle()
}
.actionSheet(isPresented: $showPaymentSheet) {
self.actionSheet
}
.onReceive(Just(paymentType)) { // <- add here
guard !$0.isEmpty else { return }
self.someOtherFunc()
}
}
var actionSheet: ActionSheet {
...
}
func someOtherFunc() {
print(paymentType)
}
}
但是,我建议将逻辑移至单独的类并保持 View clean。还有为什么paymentType = ""
?如果无法设置,您可能应该使用它nil
。为什么你首先需要它是可观察的?您还可以为付款类型创建单独的枚举。
通过以上修改,我们可以编写一个更新的示例:
enum PaymentType: String {
case cash = " Cash"
case bank = " Bank Transfer"
...
}
class PaymentHandler: ObservableObject {
func pay(_ paymentType: PaymentType) {
// print(paymentType.rawValue) // do something with `paymentType`
}
}
struct ContentView: View {
@ObservedObject private var vm = ViewModel()
@State private var showPaymentSheet = false
var body: some View {
Button("Choose payment") {
self.showPaymentSheet.toggle()
}
.actionSheet(isPresented: $showPaymentSheet) {
self.actionSheet
}
}
var actionSheet: ActionSheet {
ActionSheet(title: Text("Payment Method"), buttons: [
.default(Text(PaymentType.cash.rawValue)) { self.vm.pay(.cash) },
.default(Text(PaymentType.bank.rawValue)) { self.vm.pay(.bank) },
.cancel(),
])
}
}
推荐阅读
- python - 存储已检查顶点的图最短路径
- xcode - Xcode 12 上的催化剂目标未运行 XCode 单元测试
- compiler-construction - Wasm 规范说明
- python - 从相同索引位置的多个列表中删除元素
- django - 如何使用 Django Rest Framework 有效管理缓存(Redis)?
- django - 检查循环内数据库中是否存在记录的有效方法?
- java - 我可以在嵌套在另一个文档中的文档中的字段上创建 MongoDB 文本索引吗?(爪哇)
- c - IAR Embedded Workbench "va_list_ 未定义
- css - 仅使用类禁用 div 的单击处理程序
- python - Raspberry Pi/Python——如何控制屏幕消隐?