Jim
Jim

Reputation: 9234

SwiftUI. How to filter ViewBuilder childs?

I'm very curios how .swipeActions of List view implemented

This is how .swipeActions looks like

List {
        Text("Test")
            .swipeActions {
                Button("Action1") {}
                Button("Action2") {}
            }
    }

.swipeActions accepts ViewBuilder as a content

The interesting part is If I add anything else then Button, it will be ignored.

List {
        Text("Test")
            .swipeActions {
                Button("Action1") {}
                Text("Test")
                Button("Action2") {}
            }
    }

Text is ignored here !

How to achieve this ?

I want to make custom View with similar functionality.

How to create ViewModifier that takes ViewBuilder as parameter and then filter everything except Button ?

Upvotes: 1

Views: 50

Answers (1)

Sweeper
Sweeper

Reputation: 271410

The Texts are technically not "filtered out" by swipeActions. As far as swipeActions is concerned, the Texts exist.

It is when the "backend" of SwiftUI (whatever is creating the actual UICollectionView cells from your View structs) sees these views, that the Texts get discarded. That code doesn't know how to deal with Texts.

A similar thing happens in Menu, .tabItem, etc. These only support a subset of SwiftUI views, but it still compiles if you write unsupported views in their view builders.

Obviously, you don't have access to the "backend" of SwiftUI, so you cannot do the same.

You can, however, disallow non-Buttons at compile time, by writing your own version of @ViewBuilder that only builds Buttons:

@resultBuilder
enum ButtonsBuilder {
    static func buildBlock<each L>(_ content: repeat Button<each L>) -> TupleView<(repeat Button<each L>)> where repeat each L : View {
        ViewBuilder.buildBlock(repeat each content)
    }
}

and have your modifier take a @ButtonsBuilder instead of @ViewBuilder. But unlike a @ViewBuilder, you cannot use if/switch and other control flow structures.

Upvotes: 0

Related Questions