Always receiving .systemMedium when requesting Environment widget family

Viewed 206

I'm trying to get the right widget family in a view, but I'm always getting .systemMedium value. This is my view:

import SwiftUI

struct MyView: View
{
    @Environment(\.widgetFamily) var family

    let entry: MyEntry

    @ViewBuilder
    var body: some View
    {
        switch family
        {
        case .systemSmall:
           Text("systemSmall")
        case .systemMedium:
           Text("systemMedium")
        case .systemLarge:
           Text("systemLarge")
        case .systemExtraLarge:
           Text("systemExtraLarge")
        }
    }
}

Any ideas why this is happening? Thanks.

1 Answers

Cautionary tale, do NOT copy the below code blindly!

For me, at first this was happening for the previews in Xcode, so I searched around and implemented these extensions:

// DEBUG
extension WidgetFamily: EnvironmentKey {
    public static var defaultValue: WidgetFamily = .systemSmall
}

extension EnvironmentValues {
  var widgetFamily: WidgetFamily {
    get { self[WidgetFamily.self] }
    set { self[WidgetFamily.self] = newValue }
  }
}

as well as specifying the family environment directly for the previews:

Group {
   SWidgetEntryView(entry: SimpleEntry(date: Date()))
     .previewContext(WidgetPreviewContext(family: .systemSmall))
     .environment(\.widgetFamily, .systemSmall)
   SWidgetEntryView(entry: SimpleEntry(date: Date()))
     .previewContext(WidgetPreviewContext(family: .systemMedium))
     .environment(\.widgetFamily, .systemMedium)
}

This will solve the issue during preview, but will mess up the widgets on the device, as it overrides the widgetFamily environment variable. All widget sizes will have the incorrect family environment that you specify for defaultValue.

If this kind of problem is happening for you on the device, you probably implemented a similar extension to make previews work. Removing it will fix the issue on the device. I'm not sure what's the correct fix for the previews.

Related