blob: 2c99dec856ef12f939de318b2da74d3b9290a80b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
//
// CustomToggle.swift
// MullvadVPN
//
// Created by Jon Petersson on 2024-11-13.
// Copyright © 2025 Mullvad VPN AB. All rights reserved.
//
import SwiftUI
/// Custom (default) toggle style used for switches.
struct CustomToggleStyle: ToggleStyle {
private let width: CGFloat = 48
private let height: CGFloat = 30
private let circleRadius: CGFloat = 23
var disabled = false
let accessibilityId: AccessibilityIdentifier?
var infoButtonAction: (() -> Void)?
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.label
.opacity(disabled ? 0.2 : 1)
if let infoButtonAction {
Button(action: infoButtonAction) {
Image(.iconInfo)
}
.adjustingTapAreaSize()
.tint(.white)
}
Spacer()
ZStack(alignment: configuration.isOn ? .trailing : .leading) {
Capsule(style: .circular)
.frame(width: width, height: height)
.foregroundColor(.clear)
.overlay(
RoundedRectangle(cornerRadius: circleRadius)
.stroke(
Color(.white.withAlphaComponent(0.8)),
lineWidth: 2
)
)
.opacity(disabled ? 0.2 : 1)
Circle()
.frame(width: circleRadius, height: circleRadius)
.padding(3)
.foregroundColor(
configuration.isOn
? Color(uiColor: UIColor.Switch.onThumbColor)
: Color(uiColor: UIColor.Switch.offThumbColor)
)
.opacity(disabled ? 0.4 : 1)
}
.accessibilityIdentifier(accessibilityId?.asString ?? "")
.onTapGesture {
toggle(configuration)
}
.adjustingTapAreaSize()
}
}
private func toggle(_ configuration: Configuration) {
withAnimation(.easeInOut(duration: 0.25)) {
configuration.isOn.toggle()
}
}
}
|