ARTICLE AD BOX
I’m using SwiftUI’s native Toggle with the switch style. I want to change only the off (not-selected) track background color, while keeping the native iOS switch appearance and behaviour.
I tried building a custom ToggleStyle to control the track color, but that means I’m no longer using the native switch rendering (the look/feel and animation don’t perfectly match the system switch).
Here’s a simplified version of what I have:
import SwiftUI public struct CustomSwitch<Content: View>: View { @Binding private var isOn: Bool private let content: Content public init( isOn: Binding<Bool>, @ViewBuilder content: () -> Content ) { self._isOn = isOn self.content = content() } public var body: some View { Toggle(isOn: $isOn) { content } .toggleStyle(CustomSwitchToggleStyle()) } } private struct CustomSwitchToggleStyle: ToggleStyle { func makeBody(configuration: Configuration) -> some View { HStack { configuration.label Spacer() ZStack { Capsule() // want custom OFF color .fill(configuration.isOn ? Color.green : Color.gray) .frame(width: 51, height: 31) Circle() .fill(Color.white) .frame(width: 27, height: 27) .shadow(radius: 2) .offset(x: configuration.isOn ? 10 : -10) } .onTapGesture { withAnimation(.easeInOut(duration: 0.2)) { configuration.isOn.toggle() } } } } }Problem: this custom implementation does not keep the native switch appearance: it’s close, but still differs from the system component.
I also tried using the native switch:
Toggle("Example", isOn: $isOn) .toggleStyle(.switch) .tint(.green)Question
Is it possible in SwiftUI to change only the off track (not-selected) background color of the native switch-style Toggle without overriding/replacing the native appearance?
If not, what’s the recommended approach to achieve this while staying as close to native as possible (no UIKit wrapper with UISwitch)?
