如何使按钮有条件地隐藏或禁用?

问题描述 投票:0回答:8

如何切换按钮是否隐藏?
我们有非条件 .hidden() 属性;但我需要有条件版本。

注意:我们确实有 .disabled(bool) 属性可用,但没有 .hidden(bool)

struct ContentView: View {
    var body: some View {
        ZStack {
            Color("SkyBlue")
            VStack {
                Button("Detect") {
                    self.imageDetectionVM.detect(self.selectedImage)
                }
                .padding()
                .background(Color.orange)
                .foreggroundColor(Color.white)
                .cornerRadius(10)
                .hidden() // ...I want this to be toggled.
            }
        }
    }
}
button swiftui
8个回答
21
投票

我希望

hidden
修饰符稍后获得参数,但从那时起,改为设置 alpha:

@State var shouldHide = false

var body: some View {
    Button("Button") { self.shouldHide = true }
    .opacity(shouldHide ? 0 : 1)
}

14
投票

对我来说,当您不想看到它时,将

frame
的高度设置为零非常有效。当你想要计算出的大小时,只需将其设置为
nil

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

如果您除了隐藏它之外还想禁用它,您可以使用切换布尔值设置

.disabled

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

7
投票

您可以利用 SwiftUI 的新双向绑定并添加 if 语句:

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

与将不透明度设置为 0 相比,这样做的好处是,它将消除 UI 中因按钮仍在视图中而导致的奇怪间距/填充,只是不可见(如果按钮位于其他视图组件之间,即).


7
投票

这里的所有答案都专门针对有条件隐藏的按钮。

我认为可能有帮助的是有条件地制作修饰符本身,例如: .hidden 表示按钮/视图,或者 .italic 表示文本等..

使用扩展。

要使文本有条件地斜体,很容易,因为 .italic 修饰符返回文本:

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

然后像这样应用条件斜体:

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

但是对于 Button 来说这很棘手,因为 .hidden 修饰符返回“某些视图”:

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

然后像这样应用条件隐藏:

@State private var toggle = false
Button("myButton", action: myAction)
    .hiddenConditionally(isHidden: toggle)

4
投票

您可以使用条件语句轻松隐藏 SwiftUI 中的视图。

struct TestView: View{
    
    @State private var isVisible = false
    
    var body: some View{
        
        if !isVisible {
            HStack{
                Button(action: {
                    isVisible.toggle()
                    // after click you'r view will be hidden
                }){
                    Text("any view")
                }
            }
        }
        
    }
}

1
投票

它并不总是一个漂亮的解决方案,但在某些情况下,有条件地添加它也可能有效:

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

不显示的情况下会出现空格的问题,根据具体的布局,可能或多或少有问题。这可以通过添加一个

else
语句来解决,或者添加一个同等大小的空白。


0
投票
@State private var isHidden = true       
VStack / HStack
       if isHidden {
                            Button {
                                if !loadVideo(),
                                   let urlStr = drill?.videoURL as? String,
                                   let url = URL(string: urlStr) {
                                    player = VideoPlayerView(player: AVPlayer(), videoUrl: url)
                                    playVideo.toggle()
                                }
                            } label: {
                                Image(playVideo ? "ic_close_blue" : "ic_video_attached")
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(width: 50)
                            }
                            .buttonStyle(BorderlessButtonStyle())
                        }
    
     .onAppear {
                    if shouldShowButton {
                        isHidden = false
                    } else {
                        isVideoButtonHidden = true
                    }
                }

0
投票
struct Visibility: ViewModifier
{
    let isHidden: Bool
    
    func body(content: Content) -> some View {
        content
            .opacity(isHidden ? 0 : 1)
            .frame(height: isHidden ? 0 : nil)
    }
}

extension View
{
    func hidden(_if: Bool) -> some View {
        modifier(Visibility(isHidden: _if))
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.