Swift package with a SwiftUI control that mimics the SwiftUI Picker in the segmented style (pre-glass).
Note: I have no plans to add Apple's Liquid Glass styling myself but I welcome a PR to do so.
Replicates the behavior of the native control:
- Drag the selected segment to change value
- Touch on an unselected segment to change value
- Cancel a touch by dragging away vertically from the segment
Visually, the replication is not exact, but it is IMO close. In particular:
- Touching on the selected segment shrinks the indicator by a small amount
- Touching on an unselected segment grays the text of the touched segment
- Segment dividers adjacent to the selected segment disappear
- All interface changes are animated just like the native control
Additional features:
- Honors the
accentColorcolor out of the box (unlike the native control) - Easy to create 1-based numeric segments -
.init(selectedIndex: $selected, count: 4) - Easy to create segments using text labels -
.init(selectedIndex: $selected, ["One", "Two", "Buckle", "Shoe"]) - Segments can have their own custom views by providing your own
@ViewBuildermethod - Supports custom styling of the segment view's foreground via your own
ShapeStylemethod - Supports disabling animations via custom view modifier
disableAnimations
Simply add the brh-segment-control package to your Package.swift file or add via Xcode.
dependencies: [
.package(url: "https://github.com/bradhowes/brh-segmented-control", from: "1.0.0"),
],
...
.target(
name: "MyView",
dependencies: [
.product(name: "BRHSegmentedControl", package: "brh-segmented-control")
]
),
For examples of how to use, see the PreviewContent struct in BRHSegmentedControl.swift. There are also the
unit tests that exercise the API which show additional examples.
The default view builder methods are in BRHSegmentedControlSupport.swift. Creating custom ones
is easy and offers greater control of segment content. There are two versions, one taking one Int argument, and
another that takes an Int and a String. The second one is required when you provide a collection of strings in the
init method. The first argument is the segment's index to generate, and the second argument is the value from the
collection given in the init.
The control will switch selections when clicked on, but currently there is no visible change in appearance when the click takes place. This can be fixed with some minor effort.
I wrote all of the code in this repository with the exception of the Color extension to allow for light/dark color
selecting in code. That comes courtesy of Jesse Squires's blog post. In my own AUv3 project I first started
to use CustomizableSegmentedControl by Tyoma Zagoskin, but I then decided to try and replicate Apple's
implementation and so here we are. Finally, this post on StackOverflow by Benzy Neez helped me wire up
the DragGesture correctly to handle drag interactions with the segment. It was truly the missing piece that magically
brought everything together where I could at least mimic if not fully replicate the little details in Apple's
implementation.
