How do you make a Button conditionally hidden or disabled?

后端 未结 5 420
囚心锁ツ
囚心锁ツ 2021-01-12 14:08

How do I toggle the presence of a button to be hidden or not?
We have the non-conditional .hidden() property; but I need the conditional version.

Note: w

相关标签:
5条回答
  • 2021-01-12 14:46

    all the answers here works specifically for a button to be hidden conditionally.

    What i think might help is making a modifier itself conditionally e.g: .hidden for button/view, or maybe .italic for text, etc..

    Using extensions.

    For text to be conditionally italic it is easy since .italic modifier returns Text:

    extension Text {
        func italicConditionally(isItalic: Bool) -> Text {
            isItalic ? self.italic() : self
        }
    }
    

    then applying conditional italic like this:

    @State private var toggle = false
    Text("My Text")
        .italicConditionally(isItalic: toggle)
    

    However for Button it is tricky, since the .hidden modifier returns "some view":

    extension View {
        func hiddenConditionally(isHidden: Bool) -> some View {
            isHidden ? AnyView(self.hidden()) : AnyView(self)
        }
    }
    

    then applying conditional hidden like this:

    @State private var toggle = false
    Button("myButton", action: myAction)
        .hiddenConditionally(isHidden: toggle)
    
    0 讨论(0)
  • 2021-01-12 15:00

    I hope hidden modifier gets argument later, but since then, Set the alpha instead:

    @State var shouldHide = false
    
    var body: some View {
        Button("Button") { self.shouldHide = true }
        .opacity(shouldHide ? 0 : 1)
    }
    
    0 讨论(0)
  • 2021-01-12 15:04

    You can utilize SwiftUI's new two-way bindings and add an if-statement as:

    struct ContentView: View {
    
        @State var shouldHide = false
    
        var body: some View {
            ZStack {
                Color("SkyBlue")
                VStack {
                    if !self.$shouldHide.wrappedValue { 
                        Button("Detect") {
                            self.imageDetectionVM.detect(self.selectedImage)
                        }
                        .padding()
                        .background(Color.orange)
                        .foregroundColor(Color.white)
                        .cornerRadius(10)
                    }
                }
            }
        }
    }
    

    The benefit of doing this over setting the opacity to 0 is that it will remove the weird spacing/padding from your UI caused from the button still being in the view, just not visible (if the button is between other view components, that is).

    0 讨论(0)
  • 2021-01-12 15:06

    It isn't always going to be a pretty solution, but in some cases, adding it conditionally may also work:

    if shouldShowMyButton {
        Button(action: {
            self.imageDetectionVM.detect(self.selectedImage)
        }) {
            Text("Button")
        }          
    }
    

    There will be an issue of the empty space in the case when it isn't being shown, which may be more or less of an issue depending on the specific layout. That might be addressed by adding an else statement that alternatively adds an equivalently sized blank space.

    0 讨论(0)
  • 2021-01-12 15:07

    For me it worked perfectly to set the frame's height to zero when you do not want to see it. When you want to have the calculated size, just set it to nil:

    SomeView
        .frame(height: isVisible ? nil : 0)
    

    If you want to disable it in addition to hiding it, you could set .disabled with the toggled boolean.

    SomeView
        .frame(height: isVisible ? nil : 0)
        .disabled(!isVisible)
    
    0 讨论(0)
提交回复
热议问题