|
| 1 | +--- |
| 2 | +title: 'Hiding SwiftUI View' |
| 3 | +author: 'Clive Liu' |
| 4 | +layout: post |
| 5 | +tags: [Swift, SwiftUI] |
| 6 | +--- |
| 7 | + |
| 8 | +When building user interfaces, it’s common to show or hide views based on state. In SwiftUI, there are several options: |
| 9 | + |
| 10 | +1. A simple `if-else` statement |
| 11 | +2. The `.hidden()` modifier |
| 12 | +3. The `.opacity(_:)` modifier |
| 13 | + |
| 14 | +## `if-else` |
| 15 | + |
| 16 | +```swift |
| 17 | +if condition { |
| 18 | + MyView() |
| 19 | +} |
| 20 | + |
| 21 | +if condition { |
| 22 | + MyView() |
| 23 | +} else { |
| 24 | + MyOtherView() |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +Notes: |
| 29 | +- The view’s structural identity changes when the condition toggles, which resets any internal state. |
| 30 | +- View transitions are used instead of standard property animations. |
| 31 | +- Since views are inserted or removed from the hierarchy, layout may shift unexpectedly. |
| 32 | + |
| 33 | +Use this approach when view state preservation or layout consistency are not required. |
| 34 | + |
| 35 | +## `.hidden()` Modifier |
| 36 | + |
| 37 | +If you need to preserve layout, you can do this: |
| 38 | + |
| 39 | +```swift |
| 40 | +MyView() |
| 41 | + .hidden() |
| 42 | +``` |
| 43 | + |
| 44 | +However, the `.hidden()` modifier **doesn't accept a boolean**, so you can’t directly control visibility conditionally—an odd limitation. |
| 45 | + |
| 46 | +One workaround is a custom modifier, for example: |
| 47 | + |
| 48 | +```swift |
| 49 | +extension View { |
| 50 | + |
| 51 | + func hidden(_ hide: Bool) -> some View { |
| 52 | + self.modifier(HiddenModifier(hide: hide)) |
| 53 | + } |
| 54 | +} |
| 55 | + |
| 56 | +fileprivate struct HiddenModifier: ViewModifier { |
| 57 | + |
| 58 | + let hide: Bool |
| 59 | + |
| 60 | + func body(content: Content) -> some View { |
| 61 | + content |
| 62 | + .hidden() |
| 63 | + .overlay { |
| 64 | + if !hide { |
| 65 | + content |
| 66 | + } |
| 67 | + } |
| 68 | + } |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +## `.opacity(_:)` Modifier |
| 73 | + |
| 74 | +But a simpler solution is to toggle opacity: |
| 75 | + |
| 76 | +```swift |
| 77 | +extension View { |
| 78 | + |
| 79 | + func hidden(_ hide: Bool) -> some View { |
| 80 | + self.opacity(hide ? 0 : 1) |
| 81 | + } |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +This can feel unconventional, and you might worry about accessibility. However, per WWDC24 [Catch up on accessibility in SwiftUI](https://developer.apple.com/videos/play/wwdc2024/10073/?time=470), when a view is visually hidden (for example, when its opacity is zero), SwiftUI will automatically hide the element from accessibility technologies such as VoiceOver. |
| 86 | + |
| 87 | +Therefore, this approach is safe for conditional hiding. |
0 commit comments