SwiftUI -将值传递给enum



我正在创建一些可重用的视图,但是为了使问题和示例简短,我现在只分享有限的代码。假设我已经创建了一个CustomActionsView,它可以根据需要以不同的样式显示不同的消息和按钮。

我创建了一个视图构建器,它根据不同的输入返回视图。下面共享代码:

import SwiftUI
struct Destinations {
var messageText: String = ""
var viewStyle: Int = 0
@Binding var showingModal:Bool
enum CustomDestinations: Int, CaseIterable, Hashable {
case view1 = 0, view2 = 1, view3 = 2
@ViewBuilder var view: some View {
switch self {
case .view1: CustomActionsView(mainMessageText: self.messageText, viewStyle: 0, showingModal: self.$showingModal)
case .view2: CustomActionsView(mainMessageText: self.messageText, viewStyle: 1, showingModal: self.$showingModal)
case .view3: CustomActionsView(mainMessageText: self.messageText, viewStyle: 2, showingModal: self.$showingModal)
}
}
}
}

我在我的应用程序的其他地方创建了一个类似的enum(没有包装在struct中),它工作得很好,因为视图不需要任何输入。然而,在这种情况下,CustomActionView期望messageText, viewStyle和一个绑定属性,所以我把它包装在一个结构中,我认为我可以从结构中分配属性值,它会工作。

但是有了这个设计,我得到了以下错误和其他2个属性的类似错误:

Value of type 'Destinations.CustomDestinations' has no member 'messageText'

我也不能在enum中存储属性。

可以在enum中传递值给view吗?

注意:我正在使用最小watchOS版本为7.0的手表应用程序。

谢谢!

在这种情况下,我们可以使用函数代替可计算属性,并通过参数获得所需的东西,如

enum CustomDestinations: Int, CaseIterable, Hashable {
case view1 = 0, view2 = 1, view3 = 2
@ViewBuilder 
func view(message: String, isModal: Binding<Bool>) -> some View {
switch self {
case .view1: CustomActionsView(mainMessageText: message, viewStyle: 0, showingModal: isModal)
case .view2: CustomActionsView(mainMessageText: message, viewStyle: 1, showingModal: isModal)
case .view3: CustomActionsView(mainMessageText: message, viewStyle: 2, showingModal: isModal)
}
}
}

首先,在不是视图的结构体中使用@Binding的方式必然会在某些时候给您带来麻烦。绑定是特定于swifui的,在上下文之外使用它们必然会在某些时候导致错误和意外行为。

如果你想在使用枚举的情况下传递一些数据,你必须使用关联值:

enum Foo {
case number(Int)
case text(String)
}
switch Foo.text("Hello, World") {
case .number(let number):
print("the number is: (number)")
case .text(let text):
print("the text is: (text)")
}

也就是说,使用关联值与原始值不兼容,这意味着您需要放弃IntCaseIterable一致性。

我认为这是过于复杂的事情当Destinations不是一个视图,所以为什么不只是一个视图?

struct Destinations: View {
var messageText: String = ""
var viewStyle: Int = 0
@Binding var showingModal: Bool
var body: some View {
CustomActionsView(
mainMessageText: messageText,
viewStyle: 0,
showingModal: $showingModal
)
}
}

然后,您可以删除整个枚举舞蹈。