5

Is it possible to depend on multiple conditions in SwiftUI? For example to show a sheet:

.sheet(isPresented: $stateA && $stateB, content: { ... }) // this is not working

Or is a different approach known?

3 Answers 3

3

"I can only show you the door..." (c) Morpheus

Today is a day of overloaded operators :^) - previous was here, here is for your case (tested with Xcode 11.3+)

extension Binding where Value == Bool {

    static func &&(_ lhs: Binding<Bool>, _ rhs: Binding<Bool>) -> Binding<Bool> {
        return Binding<Bool>( get: { lhs.wrappedValue && rhs.wrappedValue }, 
                              set: {_ in })
    }
}

struct TestCustomBinding: View {
    @State private var isFirst = true
    @State private var isSecond = false
    var body: some View {
        VStack {
            Button("TestIt") {
                self.isSecond = true
            }
            .sheet(isPresented: $isFirst && $isSecond) {
                Button("CloseMe") {
                    // sheet MUST be closed explicitly via one of states !
                    self.isSecond = false 
                }
            }
        }
    }
}

Sign up to request clarification or add additional context in comments.

1 Comment

.-) you can even define || operator, none could stop you ... I don't like to stop you, but see my updated answer
2

no, it is not possible! isPresented accept Binding, that means the state is updated if sheet will be dismissed. Which of stateA, stateB have to be changed? or both of them? Even though someone will try to define && operator where left and right side is Binding, that is very bad idea. Don't try to do it!

Move the logic to your model, better outside of any View.

UPDATE (for Asperi)

this is valid code (with your extension)

struct ContentView: View {
    @State private var isFirst = true
    @State private var isSecond = false
    var body: some View {
        VStack {
            Button("TestIt") {
                self.isSecond = true
            }
            .sheet(isPresented: $isFirst && $isSecond) {
                Text("A")
            }
        }
    }
}

Try it! Pressing TestIt will open the sheet. There is no Button to "go back", but you can dismiss it with well known gesture. And try to press TestIt again ...

Comments

0

It is possible to get different conditions from a variable.

struct ChangingButton: View { 
var text: String
var onButton: String
var offButton: String 
var changeButton: Bool

 var buttonCondition: String {
    if isOn {
        return isOnImage
    } else {
        return isOffImage
    }
}
var body: some View {

    Button(action: {
        action()
    }
    , label: {
        VStack {
           Image(systemName: buttonCondition)             
            Text(text)
        }
    })
 }
}
struct ChangingButton_Previews: PreviewProvider {
static var previews: some View {
    ChangingButton(text: "My Button", onButton: "on", offButton: "off", changeButton: true, action: {
    }).background(Color.black)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.