Detect if EmptyView is returned by switch function

Viewed 16

I want to detect if a function with a switch case is returning an EmptyView or not. The goal is that when there is an EmptyView() returned, that no sheet is presented or the sheet is closed immediately after it was presented. I know that I could just extend my protocol ProfileEntryable with another parameter, e.g. var isEmpty: Bool { get } but the goal is to detect the EmptyView from the function without the need of another manual parameter.

/// Returns the view to be displayed
@ViewBuilder
func getView(isPresented: Binding<Bool>, container: Container) -> some View {
    switch self {
    case .reminders:
        RemindersView(isPresented: isPresented)
    case .hasPlus:
        EmptyView()
    case .sendMessage:
        ActivityViewControllerRepresentable(isPresented: isPresented) {
            container.sendMail()
        }
    }
}

The returned view getView() is presented in a Sheet:

@State private var contentType: ProfileEntryable

var body some View {
   ...
    .sheet(isPresented: $isSheetPresented, // GOAL: no sheet should be presented in case of EmptyView
           content: {
            SheetView(profileEntryType: $contentType,
                                  isPresented: $isSheetPresented) }
        )
}

/// Workaround to detect every state change in parent via binding (SwiftUI bug)
struct SheetView<T: ProfileEntryable>: View {
    
    @Environment(\.container) var container
    
    @Binding var profileEntryType: T
    
    @Binding var isPresented: Bool
    
    var body: some View {
        profileEntryType.getView(isPresented: $isPresented, container: container)
         
    }
}

protocol ProfileEntryable {
    
    associatedtype T: View

    /// Returns the view to be displayed
    @ViewBuilder
    func getView(isPresented: Binding<Bool>, container: Container) -> T
    
}

What I have tried to do is using a generic struct, but it doesn't work. Content == EmptyView is never initialised:

struct CheckContent<Content: View> {

    var content: (Binding<Bool>, Container) -> Content

    var isEmptyView: Bool

    private init(content: @escaping (Binding<Bool>, Container) -> Content, isEmptyView: Bool) {
        self.content = content
        self.isEmptyView = isEmptyView
    }

    init(@ViewBuilder content: @escaping (Binding<Bool>, Container) -> Content) {
        self.init(content: content, isEmptyView: false)
    }

    init() where Content == EmptyView {
        self.init(content: { _,_ in EmptyView() }, isEmptyView: true)
    }
}
0 Answers
Related