SwiftUI双向绑定到枚举案例中ObservableObject内部的值 [英] SwiftUI two-way binding to value inside ObservableObject inside enum case

查看:438
本文介绍了SwiftUI双向绑定到枚举案例中ObservableObject内部的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试观察ObservableObject中包含的ObservableObject中的bool值的变化.这是我要达到的目标的一个示例,但是使用当前的方法,我会收到错误Use of unresolved identifier '$type1Value'.

I am trying to observe changes of a bool value contained in an ObservableObject which is a value in an enum case. Here is an example of what I am trying to achieve but with the current approach I receive the error 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将从CustomEnum值的Array接收myCustomEnum值.这有可能吗?如果没有,我有什么选择?谢谢!

I am trying to update the value of isChecked from the interface but since I want to have the ObservableObject which contains the property in an enum like CustomEnum not sure how to do it or if it is even possible. I went for an enum because there will be multiple enum options with different ObservableObject values and the Parent will generate different subviews depending on the CustomEnum option. If it makes any relevance the Parent will receive the myCustomEnum value from an Array of CustomEnum values. Is this even possible? If not, what alternatives do I have? Thank you!

推荐答案

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

Well, never say never... I've found interesting solution for this scenario, which even allows to remove AnyView. Tested with Xcode 11.4 / iOS 13.4

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

Provided full testable module, just in case.

// 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)
    }
}

这篇关于SwiftUI双向绑定到枚举案例中ObservableObject内部的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆