Reputation: 9234
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
Reputation: 271410
The Text
s are technically not "filtered out" by swipeActions
. As far as swipeActions
is concerned, the Text
s exist.
It is when the "backend" of SwiftUI (whatever is creating the actual UICollectionView
cells from your View
structs) sees these views, that the Text
s get discarded. That code doesn't know how to deal with Text
s.
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-Button
s at compile time, by writing your own version of @ViewBuilder
that only builds Button
s:
@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