iOS widget previews with different size family

While working through Part II the Widget code-along from WWDC, I thought I would add a separate preview for each size, just as an exercise for myself.

Code Block struct EmojiRangerWidget_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            EmojiRangerWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), character: .panda))
                .previewContext(WidgetPreviewContext(family: .systemSmall))
            EmojiRangerWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), character: .panda))                .previewContext(WidgetPreviewContext(family: .systemMedium))
        }
    }
}


This works, giving me two previews of the correct size. Unfortunately, the smaller preview is trying to layout the medium's view within its given space.

I'm assuming that this is because the @Environment for the widgetFamily wasn't configured correctly, so I thought I'd add it like this:

Code Block
.environment(\.widgetFamily, .systemSmall)


I was guessing that something like this might be possible, because I have seen a similar situation where a preview is created for a dark mode like this:

Code Block
.environment(\.colorScheme, .dark)


Alas, my attempt to set the widgetFamily environment doesn't work. It gives me a this error:

Key path value type 'WritableKeyPath<EnvironmentValues, WidgetFamily>' cannot be converted to contextual type 'KeyPath<EnvironmentValues, WidgetFamily>'

Am I close? Is there some way to inject the widget family environment, or is there a bug that fails to bind the WidgetPreviewContext(family: .systemSmall) that I'm already passing?



  • I'm experiencing the same issue with Xcode 13.2, did this ever get resolved for you?

  • I am as well with Xcode 13.2, and I didn't see this with the previous version I was running (13.1). Is there an easy solution, or do I need to embed the family within the entry instead of reading it from the environment (which is not what is recommended...)?

  • unfortunately, this still happens in Xcode 13.2.1. are there any known workarounds?

Add a Comment

Replies

Hey Pohl, the original code you posted (setting the previewContext on each view) should work correctly in Developer Beta 2. If you still see the issue in beta 2 please let us know by reporting it in feedback assistant. Thanks!
Thank you, I have submitted FB7980114 – an example project through Feedback Assistant that reproduces the problem.
Just to let you know: I do have the exact same problem with Xcode 12 beta 5.

Just to let you know: I do have the exact same problem with Xcode 12 beta 5.
@pi80223

Same here. Got the same issue on Xcode 12 beta 5.
  1. Overriding the .environment(\.widgetFamily, .systemSmall) triggers the same error

  2. Setting the WidgetFamily value to .systemSmall in .previewContext(WidgetPreviewContext(family:)) only resizes the preview context, but the widget view is still rendering for the .systemMedium family

@arikays and anyone else hitting issues: please do file feedback reports with included sample projects as we are unable to reproduce any problems related to the widgetFamily environment variable not having the correct value in current beta builds.
I am using Version 12.0.1 (12A7300).

Widgets are added by size to the app being serviced, but only the medium size is shown.
Below is the code.

struct SRWidgetEntryView: View {
@Environment(\.widgetFamily) private var widgetFamily
var entry: Provider.Entry
var body: some View {
Code Block
VStack {
Text(entry.date, style: .time)
switch widgetFamily {
case .systemSmall:
Text("systemSmall")
case .systemMedium:
Text("systemMedium")
case .systemLarge:
Text("systemLarge")
@unknown default: Text("unknown")
}
}
}
}

It works well when it comes to a new project, but why does this work in an existing app?

Here is a workaround to resolve Key path value type 'WritableKeyPath<EnvironmentValues, WidgetFamily>' cannot be converted to contextual type 'KeyPath<EnvironmentValues, WidgetFamily>'.

Source: https://stackoverflow.com/a/68489369

extension WidgetFamily: EnvironmentKey {

    public static var defaultValue: WidgetFamily = .systemMedium

}

extension EnvironmentValues {

  var widgetFamily: WidgetFamily {

    get { self[WidgetFamily.self] }

    set { self[WidgetFamily.self] = newValue }

  }

}
Add a Comment