Search code examples
swiftswiftuiswiftui-list

SwiftUI Optional header and footer in Section, opaque return type error


what I am trying to achieve is to have different sections in a ListView that may or may not have the footer or header text visible. Since the Section is strictly typed to have a footer or a header or both or none I have to go through all cases to create the section like in the code below. The issue I am having is that the body gives the error Function declares an opaque return type, but the return statement in its body do not have matching underlying types, so from my understanding it would like to have a unique return type I think which is not the case that I want. I am new to SwiftUI and I'm not sure how to correct the issue in this case. Also returning nil in the last case complains that 'nil' requires a contextual type. Thank you!

struct CMGeneralSettingsSectionView: View {

        @Binding var section: CMGeneralSettingsSection

        var body: some View {
            if let headerTitle = section.headerTitle {
                if let footerTitle = section.footerTitle {
                    return Section(header: Text(headerTitle),
                                   footer: Text(footerTitle)) {
                                    return Text("")
                    }
                } else {
                    return Section(header: Text(headerTitle)) {
                        return Text("")
                    }
                }
            } else {
                if let footerTitle = section.footerTitle {
                    return Section(footer: Text(footerTitle)) {
                        return Text("")
                    }
                } else {
                    return nil
                }
            }
        }
    }

Solution

  • Make your body view builder and return EmptyView instead of nil, which is not allowed due to non optional some View return type.

    Here is fixed variant

    struct CMGeneralSettingsSectionView: View {
    
            @Binding var section: CMGeneralSettingsSection
    
            @ViewBuilder
            var body: some View {
                if let headerTitle = section.headerTitle {
                    if let footerTitle = section.footerTitle {
                        return Section(header: Text(headerTitle),
                                       footer: Text(footerTitle)) {
                                        return Text("")
                        }
                    } else {
                        return Section(header: Text(headerTitle)) {
                            return Text("")
                        }
                    }
                } else {
                    if let footerTitle = section.footerTitle {
                        return Section(footer: Text(footerTitle)) {
                            return Text("")
                        }
                    } else {
                        return EmptyView()
                    }
                }
            }
        }