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
})
}
}
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!
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
}
@ViewBuilder
private func processCases() -> some View {
switch myCustomEnum {
case .option1(let type1Value):
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
}
}
}
Here is a playmaker
struct ObservedHolder<T: ObservableObject, Content: View>: View {
@ObservedObject var value: T
var content: (ObservedObject<T>.Wrapper) -> Content
var body: some View {
content(_value.projectedValue)
}
}
backup
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With