Created
February 16, 2022 15:19
-
-
Save ericlewis/bb469fc2a5f22d23b942284eec9c2856 to your computer and use it in GitHub Desktop.
An initializer overload which also pushes an environment value on toggle status to the toggle's label.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct IsToggledOnKey: EnvironmentKey { | |
static let defaultValue: Bool = false | |
} | |
extension EnvironmentValues { | |
fileprivate var _isToggledOn: Bool { | |
get { self[IsToggledOnKey.self] } | |
set { self[IsToggledOnKey.self] = newValue } | |
} | |
} | |
extension EnvironmentValues { | |
public var isToggledOn: Bool { | |
get { self[IsToggledOnKey.self] } | |
} | |
} | |
struct IsToggledOnModifier: ViewModifier { | |
let isOn: Bool | |
func body(content: Content) -> some View { | |
content.environment(\._isToggledOn, isOn) | |
} | |
} | |
extension Toggle where Label == ModifiedContent<SwiftUI.Label<Text, Image>, IsToggledOnModifier> { | |
public init(_ titleKey: LocalizedStringKey, systemImage named: String, isOn: Binding<Bool>) { | |
self.init(isOn: isOn, label: { SwiftUI.Label(titleKey, systemImage: named).modifier(IsToggledOnModifier(isOn: isOn.wrappedValue)) }) | |
} | |
public init<S>(_ title: S, systemImage named: String, isOn: Binding<Bool>) where S: StringProtocol { | |
self.init(isOn: isOn, label: { SwiftUI.Label(title, systemImage: named).modifier(IsToggledOnModifier(isOn: isOn.wrappedValue)) }) | |
} | |
public init(_ titleKey: LocalizedStringKey, image named: String, isOn: Binding<Bool>) { | |
self.init(isOn: isOn, label: { SwiftUI.Label(titleKey, image: named).modifier(IsToggledOnModifier(isOn: isOn.wrappedValue)) }) | |
} | |
public init<S>(_ title: S, image named: String, isOn: Binding<Bool>) where S: StringProtocol { | |
self.init(isOn: isOn, label: { SwiftUI.Label(title, image: named).modifier(IsToggledOnModifier(isOn: isOn.wrappedValue)) }) | |
} | |
} | |
extension LabelStyle where Self == ToggleLabelStyle { | |
public static var toggle: Self { .init() } | |
} | |
// Customize our Toggle's Label here, we can even see if it is toggled on! | |
public struct ToggleLabelStyle: LabelStyle { | |
@Environment(\.isToggledOn) | |
private var isOn | |
public init() {} | |
public func makeBody(configuration: Configuration) -> some View { | |
Label { | |
configuration.title | |
} icon: { | |
configuration.icon | |
} | |
.foregroundStyle(isOn ? .green : .primary) | |
} | |
} | |
struct ContentView: View { | |
@State | |
private var isOn = false | |
var body: some View { | |
VStack { | |
Toggle("Test toggle", systemImage: "gear", isOn: $isOn) | |
.labelStyle(.toggle) | |
} | |
.padding() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment