Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally use view in SwiftUI

Tags:

swift

swiftui

I'm trying to figure out the correct way to conditionally include a view with swiftui. I wasn't able to use the if directly inside of a view and had to use a stack view to do it.

This works but there seems like there would be a cleaner way.

var body: some View {     HStack() {         if keychain.get("api-key") != nil {             TabView()         } else {             LoginView()         }     } } 
like image 288
Michael St Clair Avatar asked Jun 09 '19 19:06

Michael St Clair


People also ask

How do I show and hide a view in SwiftUI?

Use an opacity(_:) modifier with a value of 0 so that the layout accounts for the error message whether or not it's visible. You can also use this strategy for removing a view that doesn't affect other views' placement, like a view inside an overlay(alignment:content:) modifier.

How do I return a view in SwiftUI?

on the -> View return type.

What is @ViewBuilder?

The @ViewBuilder attribute is one of the few result builders available for you to use in SwiftUI. You typically use it to create child views for a specific SwiftUI view in a readable way without having to use any return keywords.


2 Answers

The simplest way to avoid using an extra container like HStack is to annotate your body property as @ViewBuilder, like this:

@ViewBuilder var body: some View {     if user.isLoggedIn {         MainView()     } else {         LoginView()     } } 
like image 97
Yurii Kotov Avatar answered Sep 28 '22 09:09

Yurii Kotov


I needed to embed a view inside another conditionally, so I ended up creating a convenience if function:

extension View {    @ViewBuilder    func `if`<Content: View>(_ conditional: Bool, content: (Self) -> Content) -> some View {         if conditional {             content(self)         } else {             self         }     } } 

This does return an AnyView, which is not ideal but feels like it is technically correct because you don't really know the result of this during compile time.

In my case, I needed to embed the view inside a ScrollView, so it looks like this:

var body: some View {     VStack() {         Text("Line 1")         Text("Line 2")     }     .if(someCondition) { content in         ScrollView(.vertical) { content }     } } 

But you could also use it to conditionally apply modifiers too:

var body: some View {     Text("Some text")     .if(someCondition) { content in         content.foregroundColor(.red)     } } 

UPDATE: Please read the drawbacks of using conditional modifiers before using this: https://www.objc.io/blog/2021/08/24/conditional-view-modifiers/

like image 42
gabriellanata Avatar answered Sep 28 '22 07:09

gabriellanata