Skip to content

Render Picker as a spinner#15

Merged
colemancda merged 4 commits into
masterfrom
feature/picker
Jul 22, 2026
Merged

Render Picker as a spinner#15
colemancda merged 4 commits into
masterfrom
feature/picker

Conversation

@colemancda

Copy link
Copy Markdown
Member

Completes the pickable controls: Picker renders as a native Spinner, bound to its generic SelectionValue. Uses the Spinner constructors added upstream in PureSwift/Android#47.

Option extraction

The interesting part is recovering the options. Picker.body doesn't hand the renderer its rows directly — it wraps them in a generated ForEach of _PickerElements, each inside conditional content, and ForEach additionally wraps every row in an identified view. The renderer flattens that tree recursively (descending group views and identified views) down to the _PickerElement rows, then walks each row's modifiers for the tag(_:) that associates it with its selection value — the same trait-walking approach TabView uses for its tags.

Row titles come from the Text inside each row, unwrapping any modifiers around it (including the tag itself). Rows that aren't text render as an empty entry, since a spinner shows plain strings rather than arbitrary views.

The ForEach-with-data case (ForEach(items, id: \.self)), where the row identity is the selection value, is handled through the container's elements path.

Selection

Selection maps to and from adapter indices: the listener looks up the tapped position in the extracted values and writes it to the binding, guarded against no-op writes; updates set the spinner's position from the bound value. The listener is attached after the adapter so the initial selection doesn't fire a callback.

The listener bridge (SpinnerOnItemSelectedListener) follows the convention from the slider/text-field bridges: the Kotlin side collapses the interface callbacks into one external method forwarding only the position, keeping the JNI signature aligned with the Swift declaration.

The spinner spans the stack like the other horizontal controls — at its intrinsic width it collapses to just the dropdown arrow, hiding the selected value.

Verification

On the emulator: the spinner shows the selected value, the dropdown opens with all three options, and selecting one updates both the spinner and the bound @State (Apple → Banana → Cherry across builds).

@colemancda
colemancda merged commit d21109d into master Jul 22, 2026
6 checks passed
@colemancda
colemancda deleted the feature/picker branch July 22, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant