Skip to content

Commit a0d7809

Browse files
committed
Add multi-state support with Int-based selection API
1 parent 0b10a11 commit a0d7809

36 files changed

+661
-666
lines changed

Docs/BenchmarkResults.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
# SlidingToggleButton Benchmark Results
22

3-
## Results (November 27, 2025)
3+
## Results (November 28, 2025)
4+
5+
### 2-Icon Mode
6+
7+
| Metric | Value | Target |
8+
|--------|-------|--------|
9+
| First Render Time | 0.48ms | < 16.67ms (60fps) |
10+
| State Toggle Latency | 0.03ms | < 16.67ms (60fps) |
11+
| Memory Footprint | 96 bytes | < 512 bytes |
12+
| Rapid Toggle (1000x) | 5.53ms | < 1000ms |
13+
14+
### 3-Icon Mode
415

516
| Metric | Value | Target |
617
|--------|-------|--------|
7-
| First Render Time | 0.57ms | < 16.67ms (60fps) |
18+
| First Render Time | 0.50ms | < 16.67ms (60fps) |
819
| State Toggle Latency | 0.02ms | < 16.67ms (60fps) |
9-
| Memory Footprint | 152 bytes | < 512 bytes |
10-
| View Hierarchy Depth | 194 levels | < 250 levels |
11-
| Rapid Toggle (1000x) | 7.83ms | < 1000ms |
20+
| Memory Footprint | 96 bytes | < 512 bytes |
21+
| Rapid Toggle (1000x) | 5.53ms | < 1000ms |
1222

1323
**Environment:** Apple Silicon (arm64e-apple-macos14.0), Swift 6.0
1424

README.md

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SlidingToggleButton
22

3-
A minimal sliding SwiftUI toggle button.
3+
A minimal sliding SwiftUI toggle button with support for 2 or 3 states.
44

55
https://github.com/user-attachments/assets/5ce70903-8e6a-40a8-a2c2-40c88b513571
66

@@ -22,35 +22,43 @@ https://github.com/TahaTesser/SlidingToggleButton.git
2222
import SlidingToggleButton
2323

2424
struct ContentView: View {
25-
@State private var isDarkMode = false
25+
@State private var twoIconSelection = 0
26+
@State private var threeIconSelection = 0
2627

2728
var body: some View {
28-
HStack {
29-
// Horizontal Sliding Toggle Button
30-
SlidingToggleButton(value: $isDarkMode) {
29+
VStack {
30+
// 2-Icon Toggle
31+
SlidingToggleButton(selection: $twoIconSelection) {
3132
Image(systemName: "sun.max.fill")
3233
Image(systemName: "moon.fill")
3334
}
34-
// Vertical Sliding Toggle Button
35-
SlidingToggleButton(value: $isDarkMode, vertical: true) {
35+
36+
// 3-Icon Toggle
37+
SlidingToggleButton(selection: $threeIconSelection) {
3638
Image(systemName: "sun.max.fill")
39+
Image(systemName: "circle.lefthalf.filled")
3740
Image(systemName: "moon.fill")
3841
}
3942
}
4043
}
4144
}
4245
```
4346

44-
The icons are provided in a trailing closure:
45-
- First view: start icon (true state)
46-
- Second view: end icon (false state)
47+
Selection values: `0` (start), `1` (center for 3-icon), `2` (end for 3-icon)
4748

48-
`Image` views are automatically resizable. You can also use custom views:
49+
### Customization
4950

5051
```swift
51-
SlidingToggleButton(value: $isOn) {
52-
Circle().fill(.yellow)
53-
Circle().fill(.blue)
52+
SlidingToggleButton(
53+
selection: $selection,
54+
size: 32,
55+
padding: 12,
56+
backgroundColor: .blue.opacity(0.3),
57+
buttonBackgroundColor: .blue.opacity(0.6),
58+
vertical: true
59+
) {
60+
Image(systemName: "sun.max.fill")
61+
Image(systemName: "moon.fill")
5462
}
5563
```
5664

@@ -63,53 +71,13 @@ SlidingToggleButton(value: $isOn) {
6371

6472
**Swift Version:** 5.9+ (Swift 6 compatible)
6573

66-
### API Dependencies
67-
68-
The following iOS 17+/macOS 14+ APIs are used:
69-
- `phaseAnimator` - For icon bounce animations
70-
- `symbolEffect(.bounce.byLayer)` - For SF Symbol effects
71-
- `containerShape` - For tap gesture shape
72-
- `onChange(of:)` - New simplified syntax
73-
74-
## Specifications
75-
76-
![SlidingToggleButton_Specs.png](./Docs/SlidingToggleButton_Specs.png)
77-
78-
### Measurements (Horizontal)
79-
80-
| Attribute | Value |
81-
|-----------|-------|
82-
| Container Width | 48 pixels |
83-
| Container Height | 24 pixels |
84-
| Button Shape Size | 24 x 24 pixels |
85-
| Icon Size | 18 x 18 pixels |
86-
| Icon Padding | 8 pixels (All Sides) |
87-
88-
### Measurements (Vertical)
89-
90-
| Attribute | Value |
91-
|-----------|-------|
92-
| Container Width | 24 pixels |
93-
| Container Height | 48 pixels |
94-
| Button Shape Size | 24 x 24 pixels |
95-
| Icon Size | 18 x 18 pixels |
96-
| Icon Padding | 8 pixels (All Sides) |
97-
98-
### Colors
99-
100-
| Attribute | Value |
101-
|-----------|-------|
102-
| Container Background Color | `.secondary.opacity(0.3)` |
103-
| Button Background Color | `.primary.opacity(0.4)` |
104-
| Icon Color | `.white` |
105-
10674
## Performance
10775

108-
| Metric | Value |
109-
|--------|-------|
110-
| First Render | 0.57ms |
111-
| State Toggle | 0.02ms |
112-
| Memory | 152 bytes |
76+
| Metric | 2-Icon | 3-Icon |
77+
|--------|--------|--------|
78+
| First Render | 0.48ms | 0.50ms |
79+
| State Toggle | 0.03ms | 0.02ms |
80+
| Memory | 96 bytes | 96 bytes |
11381

11482
Optimized for 60fps rendering. See [Benchmark Results](./Docs/BenchmarkResults.md) for details.
11583

0 commit comments

Comments
 (0)