Isaak
Isaak

Reputation: 1379

SwiftUI: Binding to @AppStorage

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

Upvotes: 3

Views: 1983

Answers (1)

Isaak
Isaak

Reputation: 1379

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

Upvotes: 1

Related Questions