24

I want to create different layouts for each widget size (i.e. small, medium, large). How can I branch my code according to widget's size?

Şafak Gezer
  • 3,928
  • 3
  • 47
  • 49
Feridun Erbaş
  • 573
  • 1
  • 6
  • 19

2 Answers2

55

The WidgetFamily (Apple Documentation) enum as part of WidgetKit will allow you to switch upon the various sizes within your view and adjust accordingly. Set this as an @Environment variable and switch on the avaliable cases:

  • .systemSmall
  • .systemMedium
  • .systemLarge
struct WidgetView : View {
   @Environment(\.widgetFamily) var family

    @ViewBuilder
    var body: some View {
        
        switch family {
        case .systemSmall:
            Text("Small")
        case .systemMedium:
            Text("Medium")
        case .systemLarge:
            Text("Large")
        default:
            Text("Some other WidgetFamily in the future.")
        }

    }
}
pawello2222
  • 46,897
  • 22
  • 145
  • 209
Leon Storey
  • 3,274
  • 2
  • 25
  • 40
  • 2
    in my case i should write like this `@SwiftUI.Environment(\.widgetFamily) var family` – Raditya Kurnianto Oct 22 '20 at 03:13
  • 6
    This is always returning `.systemMedium`, any ideas why? – iOS Dev Nov 23 '21 at 09:07
  • The doc says "Use this value to retrieve the widget size that the user chose for a widget." I will assume then it's only after the widgets lands on screen but even after it's still medium for me using context provided from timeline works fine tho! Please update the accepted answer to avoid confusion for future readers! (I'm writing about iOS 15 not sure of the behavior for upcoming iOS 16) https://developer.apple.com/documentation/swiftui/environmentvalues/widgetfamily – dziobaczy Jun 13 '22 at 21:55
  • I like to store the bits of my UI that change in separate variables of `some View` so that the resulting content is easier to read :) No need to for single object examples like the one above, of course, but it does keep your code looking neat and helps to prevent nasty pyramids of doom. – Ash Oct 20 '22 at 08:52
8

Additionally to the accepted answer, in your Provider class methods (getTimeline, getSnapshot & placeholder) you get a context object which has a family member var.

family can be one of the three widget sizes: .systemSmall, .systemMedium & .systemLarge

Apple's official documentation.

Cosmin
  • 6,623
  • 3
  • 26
  • 28
  • 5
    Thanks! In my case only the family from `context` works, and the accepted answer approach doesn't – hyouuu Jan 09 '21 at 01:09