Change ListStyle based on horizontalSizeClass

I have stumbled upon a problem that I somehow haven't come across previously. It seems like a simple thing that can be done in SwiftUI that I can't seem to solve.

I would like to be able to switch between GroupedListStyle and InsetGroupedListStyle for compact and regular horizontal size classes, respectively.

In iOS 13, since there was no InsetGroupedListStyle, SwiftUI automatically switched between the two on change of horizontal size class, but this feature has been removed. I'd like to have thought a replacement for this had been implemented but supposedly not (that I know of).

I thought that applying
Code Block Swift
.listStyle(horizontalSizeClass == .compact ? GroupedListStyle() : InsetGroupedListStyle())
would work, but apparently not. Although they both conform to ListStyle, Xcode says they have mismatching types.

I tried then extracting it to a variable:
Code Block Swift
private var listStyle: some ListStyle {
if horizontalSizeClass == .compact {
return GroupedListStyle()
} else {
return InsetGroupedListStyle()
}
}
That didn't work resulting in the same error.
Naively, I added @ViewBuilder to see if that would work until realising these weren't views being returned.

There is no type erased list style (AnyListStyle) so that can't be applied in this situation.

I thought about making a custom ListStyle but the protocol requirements put me off. Even a custom ViewModifier didn't work.

Is this even possible in SwiftUI, or am I missing something obvious?
Post not yet marked as solved Up vote post of BabyJ Down vote post of BabyJ
1.3k views

Replies

I think I have found a temporary solution to this, albeit not the best one.

Code Block Swift
struct AdaptiveListStyle: ViewModifier {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@ViewBuilder
func makeBody(content: Content) {
if horizontalSizeClass == .compact {
content.listStyle(GroupedListStyle())
} else {
content.listStyle(InsetGroupedListStyle())
}
}
}

This will only work for just GroupedListStyle and InsetGroupedListStyle (static). I couldn’t find a way to pass in ListStyles without Xcode throwing many errors about mismatching types and generics, so I left that alone.

If anyone can fix this or provide a workaround to the original problem, it would be much appreciated.