15

When defining a view hierarchy using SwiftUI, is it possible to set the hidden() value of a View in the body of the definition?

For example:

var body: some View {
     VStack(alignment: .leading) {
          Text(self.name)
          .font(.headline)
          .hidden()
     }
}

would hide the Text object, but I would like to use a boolean property to toggle visibility.

There is a way to do this using a ternary operator and the opacity value of the view, but I was hoping for a less clever solution.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Gene Z. Ragan
  • 2,643
  • 2
  • 31
  • 41

2 Answers2

33

If you don't want to use the opacity modifier this way:

struct ContentView: View {
    @State private var showText = true

    var body: some View {
         VStack(alignment: .leading) {
              Text("Hello world")
                .font(.headline)
                .opacity(showText ? 1 : 0)
         }
    }
}

you can decide to completely remove the view conditionally:

struct ContentView: View {
    @State private var showText = true

    var body: some View {
         VStack(alignment: .leading) {
            if showText {
                Text("Hello world")
                    .font(.headline)
            }
         }
    }
}

Consider that both ways are widely used in SwiftUI. For your specific case I'd honestly use the opacity modifier, but even the removal is fine.

superpuccio
  • 11,674
  • 8
  • 65
  • 93
  • The big difference is that opacity of 0 will still preserve the space for the element (even if SwiftUI won't draw this due to optimizations), which is something you may or may not want. – Tomáš Kafka Aug 16 '22 at 08:18
0

Don't know if its still use useful because it's been a long time and I guess you found a solution since.But for anyone who's interested, we could create a modifier, which switches the visibility of the view according to a binding value :

import SwiftUI

struct IsVisibleModifier : ViewModifier{
    
     var isVisible : Bool
    // the transition will add a custom animation while displaying the 
    // view.
    var transition : AnyTransition

    func body(content: Content) -> some View {
        ZStack{
            if isVisible{
                content
                    .transition(transition)
            }
        }
    }
}

extension View {

    func isVisible(
        isVisible : Bool,
        transition : AnyTransition = .scale
    ) -> some View{
        modifier(
            IsVisibleModifier(
                isVisible: isVisible,
                transition: transition
            )
        )
    }
}

In use :

        Text("Visible")
            .isVisible(isVisible: isVisible)
            .animation(.easeOut(duration: 0.3), value: isVisible)
Ruben Mim
  • 136
  • 1
  • 6