Any better way to write multi-family Widget #Preview macro?

Hello,

In WidgetKit, I have to write multiple #Preview macros for each family the widget supports. So is there any better way to write the #Preview?

(Although I can use the legacy PreviewProvider but it does not support timeline to test transition animation.)

#import WidgetKit
#import SwiftUI

struct DailyCaffeineWidget: Widget {
    ...
}

@available(iOS 17.0, *)
#Preview("Inline", as: .accessoryInline) {
    DailyCaffeineWidget()
} timelineProvider: {
    previewTimelineProvider()
}

@available(iOS 17.0, *)
#Preview("Circular", as: .accessoryCircular) {
    DailyCaffeineWidget()
} timelineProvider: {
    previewTimelineProvider()
}

@available(iOS 17.0, *)
#Preview("Rectangular", as: .accessoryRectangular) {
    DailyCaffeineWidget()
} timelineProvider: {
    previewTimelineProvider()
}

@available(iOS 17.0, *)
#Preview("Small", as: .systemSmall) {
    DailyCaffeineWidget()
} timelineProvider: {
    previewTimelineProvider()
}

@available(iOS 17.0, *)
#Preview("Medium", as: .systemMedium) {
    DailyCaffeineWidget()
} timelineProvider: {
    previewTimelineProvider()
}

...
Answered by Developer Tools Engineer in 758989022

Hi,

There isn't a good way to have a single preview macro definition that will produce a preview for each of the families, but you can use the UI affordances at the bottom of the canvas to modify the current preview. The Canvas Device Settings will let you modify the current preview while the Variants button will let you see all the families at once in a grid by selecting Widget Context Variants.

Hope that helps!

Accepted Answer

Hi,

There isn't a good way to have a single preview macro definition that will produce a preview for each of the families, but you can use the UI affordances at the bottom of the canvas to modify the current preview. The Canvas Device Settings will let you modify the current preview while the Variants button will let you see all the families at once in a grid by selecting Widget Context Variants.

Hope that helps!

You can probably do this with something like a ForEach macro. I imagine the syntax would look something like

#ForEach(arrayOfStuff) { thing in
  #Preview(thing.description, as: thing) {
    DailyCaffeineWidth()
  } timelineProvider: {
    previewTimelineProvider()
  }
}

I don't have a macro ForEach handy, but it's probably something someone has written. Or you can write your own as a fun exercise.

Good luck.

Any better way to write multi-family Widget #Preview macro?
 
 
Q