Reputation: 1645
I'm working on a WidgetKit widget with two dynamic parameters. One of those parameters is limited to options allowed by the first. Let's say the first is the Captain, and the second is the Captain's Ship. Allowable configurations might be (ignoring canon):
Captains: [Kirk, Picard, Crunch]
Captain: Kirk, Ship: [Enterprise, Galileo]
Captain: Picard, Ship: [Enterprise, Voyager, Cube]
Captain: Crunch, Ship: [Sugar, Berry, Chocula]
I have the logic working. For example, if the user selects Picard, then taps the Ship button, only Enterprise, Voyager, and Cube are available options. The user can then choose one of those ships (say, Cube) and all is good.
However the Ship option doesn't change or reset when the Captain is changed. Let's say after the above setting, the user changes the Captain to Kirk. The Ship remains set to Cube. The user can exit the widget's configuration as if all is good, but that's an invalid configuration.
What I'd like to happen: When the user changes the Captain, the Ship changes to the first of the available Ship options for that selected Captain. I'm also fine if the Ship blanks out (requiring a choice), or the UI forces a prompt of a Ship (confined by available options), or almost anything else that prevents an invalid combination.
Is there a way to trigger a programmatic change to the second parameter based on the selection of the first?
I do not want to present an "Invalid Combination" message in the runtime Widget. I suppose my backup is to choose a ship for the user if they've made an invalid selection, but that's not ideal.
If it matters, the first parameter in the real Widget (the Captain in my example above) is truly dynamic (an array of strings provided via API). The second parameter (the Ship above) is a fixed set of three options, where any one, two, or all three could apply to any of the first parameter's selection. It is anticipated the user may create multiple Widgets with different configurations.
Upvotes: 4
Views: 1717
Reputation: 54591
Unfortunately, there's no good solution to this problem.
A possible workaround is to create separate enums per ship type. Which means that instead of Captain
and Ship
you'll have Captain
and (KirkShip
, PicardShip
, CrunchShip
).
Then you need to display them conditionally by defining parent parameter
in the Relationship
section.
This will allow you to display only the relevant parameters on the UI:
Here is the intent configuration:
The issue with the above approach is that you need to manually map intent enums to domain models. Here is a possible example:
enum Ship: String {
case enterprise, galileo, voyager, cube // ...
init?(_ ship: KirkShip) {
switch ship {
case .unknown:
return nil
case .enterprise:
self = .enterprise
case .galileo:
self = .galileo
}
}
// more inits...
}
Then use relevant ships based on the configuration.captain
parameter:
if configuration.captain == .kirk {
let ship = Ship(configuration.kirkShip)
// ...
}
Upvotes: 12