Dynamically hiding view in SwiftUI

The simplest and most common way to hide a view is like the following:

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

    var body: some View {
        VStack {
            Button("Toggle text") {
                showText.toggle()
            }

            if showText {
                Text("Hello World!")
            }
        }
    }
}

This removes the Text view from the hierarchy when showText equals false. If you wish to have an option to preserve the space or want it as a modifier, see below.


I created an extension, so you can use a modifier, like so to hide the view:

Text("Hello World!")
    .isHidden(true)

Or for complete removal:

Text("Label")
    .isHidden(true, remove: true)

The extension below is also available on GitHub here if you want to use Swift Packages: GeorgeElsham/HidingViews.


Here is the code to create the View modifier:

I recommend you use this code in its own file (remember to import SwiftUI):

extension View {
    /// Hide or show the view based on a boolean value.
    ///
    /// Example for visibility:
    ///
    ///     Text("Label")
    ///         .isHidden(true)
    ///
    /// Example for complete removal:
    ///
    ///     Text("Label")
    ///         .isHidden(true, remove: true)
    ///
    /// - Parameters:
    ///   - hidden: Set to `false` to show the view. Set to `true` to hide the view.
    ///   - remove: Boolean value indicating whether or not to remove the view.
    @ViewBuilder func isHidden(_ hidden: Bool, remove: Bool = false) -> some View {
        if hidden {
            if !remove {
                self.hidden()
            }
        } else {
            self
        }
    }
}

✅ The correct and Simplest Way:

You can set the alpha instead, this will preserve the layout space of the view too and does not force you to add dummy views like the other answers:

.opacity(isHidden ? 0 : 1)

Demo

Demo


💡 Cleaner Way! - Extend original hidden modifier:

Also, you can implement a custom function to get the visibility state as an argument:

extension View {
    func hidden(_ shouldHide: Bool) -> some View {
        opacity(shouldHide ? 0 : 1)
    }
}

Now just pass the bool to the modifier:

DatePicker($datePickerDate)
    .hidden(showDatePicker)

Note that unlike the original behavior of the hidden modifier, both of these methods preserve the frame of the hiding view.


⛔️ Don't use bad practices !!!

All other answers (including the accepted answer by @Jake) use branches instead of dependent code that cause a performance hit.

🛑 Branch example:

Branch

✅ Dependent Code example:

Dependent Code example

Returning logical SAME view for different states causes the SwiftUI to render engine to re-render and initial a view again and cause a performance hit! (see more at this WWDC session)

Tags:

Swift

Swiftui