Skip to content

Instantly share code, notes, and snippets.

@ericlewis
Created February 16, 2022 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericlewis/bb469fc2a5f22d23b942284eec9c2856 to your computer and use it in GitHub Desktop.
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.
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