1

I'd love to reuse a list layout between iOS and WatchOS, but InsetGroupedListStyle() isn't available on WatchOS.

What would be a good way to create a helper that would conditionally return InsetGroupedListStyle() on iOS and eg. PlainListStyle() on WatchOS?

I tried this, but get an error that I cannot return ListStyle (which is probably caused by SwiftUI needing to know a specific type in compile time).

View.swift

List {
    // ...
}
.listStyle(MyInsetGroupedListStyle())

Helpers.swift

public func MyInsetGroupedListStyle() -> ListStyle {
    #if os(watchOS)
        return PlainListStyle()
    #else
        return InsetGroupedListStyle()
    #endif
}

Alternate way could be specifying the listStyle inline, but swift doesn't support conditional compilation in expressions:

View.swift

List {
    // ...
}
.listStyle(#if os(watchOS) PlainListStyle() #else InsetGroupedListStyle() #endif)
Tomáš Kafka
  • 4,405
  • 6
  • 39
  • 52
  • 2
    I asked almost the exact same thing a while ago! You need to return an opaque type: https://stackoverflow.com/a/64635065/14351818 – aheze Apr 12 '21 at 14:58

2 Answers2

3

You can achieve what you want using an extension on View. This allows you to add the listStyle modifier with the parameter that you want for the OS that you want.

extension View {
    public func customListStyle() -> some View {
        #if os(watchOS)
        return self.listStyle(PlainListStyle())
        #else
        return self.listStyle(InsetGroupedListStyle())
        #endif
    }
}

You would then use it like this:

List {
    // items in list go here
}
.customListStyle()
Andrew
  • 26,706
  • 9
  • 85
  • 101
1

Use

  1. an opaque type
public var myInsetGroupedListStyle: some ListStyle {
  #if os(watchOS)
  PlainListStyle()
  #else
  InsetGroupedListStyle()
  #endif
}
  1. a closure
listStyle( {
  #if os(watchOS)
  PlainListStyle()
  #else
  InsetGroupedListStyle()
  #endif
} () )