2

In the following example how can I change the value of activeSheet based on how SwiftUI updates aArrived and bArrived?

struct ContentView: View {

    @AppStorage("didAArrive") var aArrived: Bool = false
    @AppStorage("didBArrive") var bArrived: Bool = false

    enum ActiveSheet: Identifiable {
        case aArrived, bArrived

        var id: Int {
            hashValue
        }
    }

    @State private var activeSheet: ActiveSheet?

    var body: some View {
        Text("Hello")
            .sheet(
                item: $activeSheet,
                content: { item in
                    switch item {
                    case .aArrived:
                        Text("A arrived")
                    case .bArrived:
                        Text("B arrived")
                    }
                }
            )
    }
}
Isaak
  • 1,107
  • 2
  • 11
  • 29
  • Does `whatArrived` ever change independently of `aArrived` or `bArrived`? If not, don't make it a `@State` variable, just make it a computed property. – jnpdx Jul 17 '21 at 17:10
  • I need it as the item argument for the sheet(item:) modifier so I think I need it to be State. – Isaak Jul 17 '21 at 19:26
  • That just means that it needs to be a Binding. It would help to update the question with the requirements. Otherwise, it sounds like you already know how to use onAppear and onChange. – jnpdx Jul 17 '21 at 19:38

1 Answers1

1

You can create a custom binding for the sheet which gets its value based on aArrived and bArrived. The binding value will be initialised based on aArrived or bArrived and get updated every time that either one changes.

struct ContentView: View {

    @AppStorage("didAArrive") var aArrived: Bool = false
    @AppStorage("didBArrive") var bArrived: Bool = false

    enum ActiveSheet: Identifiable {
        case aArrived, bArrived

        var id: Int {
            hashValue
        }
    }

    var body: some View {
        let sheetBinding = Binding<ActiveSheet?>(
            get: {
                if aArrived && bArrived {
                    return ActiveSheet.aArrived
                } else if aArrived {
                    return ActiveSheet.aArrived
                } else if bArrived {
                    return ActiveSheet.bArrived
                } else {
                    return nil
                }
            },
            set: { _ in }
        )
        VStack(spacing: 20) {
            Toggle("A arrived", isOn: $aArrived)
            Toggle("B arrived", isOn: $bArrived)
        }
        .sheet(
            item: sheetBinding,
            content: { item in
                switch item {
                case .aArrived:
                    Text("A arrived")
                case .bArrived:
                    Text("B arrived")
                }
            }
        )
    }
}
Isaak
  • 1,107
  • 2
  • 11
  • 29