Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check for Optional @ViewBuilder content

Tags:

swift

swiftui

The following view is the first row of a List() meant to replace a hidden Navigation Bar.

It features a back navigation button on the left, a centered title in the middle and an optional button in the right side.

The parent view is responsible for the optional right button implementation through an optional @ViewBuilder closure.

If the parent view does not implement any right button, I need to provide a default placeholder frame to ensure the title keeps centered in place.

The problem is how to check if the closure is empty, since comparing it to EmptyView gives following exception:

if self.content == EmptyView() {}

Binary operator '==' cannot be applied to operands of type '() -> Content?' and 'EmptyView'

and comparing it to nil throughs next warning:

if self.content == nil {}

Comparing non-optional value of type '() -> Content?' to 'nil' always returns false

import SwiftUI

struct TestTitle<Content: View>: View {
    @Environment(\.presentationMode) var presentation
    var caption:String
    let content: () -> Content?
    
    public init(_ caption:String, @ViewBuilder content: @escaping () -> Content? = { nil })  {
        self.caption = caption
        self.content = content
    }
    
    var body: some View {
        HStack() {
            Image(systemName: "chevron.backward")
                .onTapGesture {
                    self.presentation.wrappedValue.dismiss()
                }
            
            Spacer()
            Text(self.caption)
            Spacer()
            
            **if self.content == nil** {
                Text(" ")
                    .frame(width:32)
            } else {
                self.content()
            }
        }
    }
}
like image 208
Matias Masso Avatar asked Oct 27 '25 06:10

Matias Masso


1 Answers

A possible solution is to compare the Content type against the EmptyView:

if Content.self == EmptyView.self {
    Text(" ")
        .frame(width: 32)
} else {
    self.content()
}
like image 138
pawello2222 Avatar answered Oct 29 '25 05:10

pawello2222