SwiftUI双向绑定到枚举案例中ObservableObject内部的值

时间:2020-05-26 18:57:04

标签: ios swift binding swiftui combine

我正在尝试观察http://127.0.0.1:5000/channels.html中包含的bool值中ObservableObject值的变化。这是我要达到的目标的一个示例,但是使用当前方法,我会收到错误enum

Use of unresolved identifier '$type1Value'

我正在尝试从界面更新import SwiftUI import Combine class ObservableType1: ObservableObject { @Published var isChecked: Bool = false } enum CustomEnum { case option1(ObservableType1) } struct Parent: View { var myCustomEnum: CustomEnum var body: AnyView { switch myCustomEnum { case .option1(let type1Value): AnyView(Child(isChecked: $type1Value.isChecked)) // <- error here } } } struct Child: View { @Binding var isChecked: Bool var body: AnyView { AnyView( Image(systemName: isChecked ? "checkmark.square" : "square") .onTapGesture { self.isChecked = !self.isChecked }) } } 的值,但是由于我想让isChecked包含ObservableObject之类的属性,例如enum怎么做,或者是否有可能。我参加了一个枚举,因为将有多个具有不同的CustomEnum值的枚举选项,并且ObservableObject将根据Parent选项生成不同的子视图。如果具有任何相关性,则CustomEnum将从Parent个值的myCustomEnum中接收Array值。这有可能吗?如果没有,我有什么选择?谢谢!

2 个答案:

答案 0 :(得分:1)

好吧,永远不要说永远...我已经找到了一种有趣的解决方案,甚至可以删除AnyView。使用Xcode 11.4 / iOS 13.4进行了测试

提供了完整的可测试模块,以防万一。

// just for test
struct Parent_Previews: PreviewProvider {
    static var previews: some View {
        Parent(myCustomEnum: .option1(ObservableType1()))
    }
}

// no changes
class ObservableType1: ObservableObject {
    @Published var isChecked: Bool = false
}

// no changes
enum CustomEnum {
    case option1(ObservableType1)
}

struct Parent: View {
    var myCustomEnum: CustomEnum

    var body: some View {
        self.processCases() // function to make switch work
    }

    private func processCases() -> some View {
        switch myCustomEnum {
        case .option1(let type1Value):
            // main part !!
            return ObservedHolder(value: type1Value) { object in
                Child(isChecked: object.isChecked)
            }
        }
    }
}

// just remove AnyView
struct Child: View {
    @Binding var isChecked: Bool
    var body: some View {
        Image(systemName: isChecked ? "checkmark.square" : "square")
            .onTapGesture {
                self.isChecked = !self.isChecked
            }
    }
}

这里是组织者

struct ObservedHolder<T: ObservableObject, Content: View>: View {
    @ObservedObject var value: T
    var content: (ObservedObject<T>.Wrapper) -> Content

    var body: some View {
        content(_value.projectedValue)
    }
}

答案 1 :(得分:-1)

这可能适合您的情况:

import SwiftUI

class ObservableType1: ObservableObject {
    @Published var isChecked: Bool = false
}

enum CustomEnum {
    case option1(ObservableType1)
}

struct Parent: View {
    var myCustomEnum: CustomEnum
    var body: AnyView {
        switch (myCustomEnum) {
            case .option1:
                return AnyView(Child())
            default: return AnyView(Child())
        }
    }
}

struct Child: View {

    @ObservedObject var type1 = ObservableType1()

    var body: AnyView {
        AnyView(
            Image(systemName: self.type1.isChecked ? "checkmark.square" : "square")
            .onTapGesture {
                self.type1.isChecked.toggle()
        })
    }
}