sabius
sabius

Reputation: 784

WidgetBundle return widgets based on some logic

I have several iOS14 Home screen Widgets ready for my app and return them all in WidgetBundle like this:

@main
struct WidgetsBudle: WidgetBundle {
    @WidgetBundleBuilder
    var body: some Widget {
        Widget1()
        Widget2()
        Widget3()
    }
}

Widget2 depends on location services to work properly, but if the user hasn't granted location permissions, it doesn't really make sense to even show this widget. Can I have some logic involved in returning the widgets inside WidgetBundle body ?

Upvotes: 10

Views: 2696

Answers (2)

tenuki
tenuki

Reputation: 370

You can also control availability from within the widget configuration itself by passing an empty list to supportedFamilies. You can then include these widgets unconditionally in the WidgetBundleBuilder, but only those returning a valid configuration with a non-empty list of supported families will actually show. Something like this:

struct ExampleWidget: Widget {
    var isAvailable: Bool = true
    var body: some WidgetConfiguration {
        return StaticConfiguration(kind: "something", provider: SomeProvider()) { _ in
           return SomeView()
        }
        .configurationDisplayName("Some name")
        .description("Some description")
        .supportedFamilies(supportedFamilies)
    } 

    var supportedFamilies: [WidgetFamily] {
        isAvailable ? [.systemMedium] : []
    }
}

Then in the widget bundle you can do something like this:

@main
struct WidgetsBundle: WidgetBundle {
    @WidgetBundleBuilder
    var body: some Widget {
        ExampleWidget(isAvailable: /* whatever condition you like */)
    }
}

Upvotes: 1

ryanlintott
ryanlintott

Reputation: 99

If you want to select a widget bundle based on some logic you can do the following:

@main
struct WidgetLauncher {
    static func main() {
        if isLocationEnabled {
            WidgetBundle1.main()
        } else {
            WidgetBundle2.main()
        }
    }
    
    static var isLocationEnabled: Bool {
        /// Put your logic here
        true
    }
}

struct WidgetBundle1: WidgetBundle {
    var body: some Widget {
        Widget1()
        Widget2()
        Widget3()
    }
}

struct WidgetBundle2: WidgetBundle {
    var body: some Widget {
        Widget1()
        Widget2()
    }
}

Upvotes: 8

Related Questions