在SwiftUI中设置切换颜色

Lin*_*rth 7 toggle swift swiftui

在遵循Apple 关于用户输入教程之后,我实现了一个切换。当前,它看起来像这样:

这是产生此UI的代码:

NavigationView {
    List {
        Toggle(isOn: $showFavoritesOnly) {
            Text("Show Favorites only")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Now, I'd like the Toggle's on-color to be blue instead of green.
I tried:

Toggle(isOn: $showFavoritesOnly) {
    Text("Show Favorites only")
}
.accentColor(.blue)
Run Code Online (Sandbox Code Playgroud)
.foregroundColor(.blue)
Run Code Online (Sandbox Code Playgroud)
.background(Color.blue)
Run Code Online (Sandbox Code Playgroud)

None of these worked and I wasn't able to find any other modifiers, such as tintColor.

How do I change the color of a Toggle?

Mar*_*ens 83

SwiftUI 2.0

使用 SwitchToggleStyle

您现在只能在 SwiftUI 2.0 中为 on 位置设置色调颜色:

Toggle(isOn: $isToggleOn) {
    Text("Red")
    Image(systemName: "paintpalette")
}
.toggleStyle(SwitchToggleStyle(tint: Color.red))

Toggle(isOn: $isToggleOn) {
    Text("Orange")
    Image(systemName: "paintpalette")
}
.toggleStyle(SwitchToggleStyle(tint: Color.orange))
Run Code Online (Sandbox Code Playgroud)

切换色调颜色

SwiftUI 1.0

使用 ToggleStyle

我创建了一个新的 ToggleStyle 来更改 Toggle 的三种颜色(on color、off color 和 thumb)。

struct ColoredToggleStyle: ToggleStyle {
    var label = ""
    var onColor = Color(UIColor.green)
    var offColor = Color(UIColor.systemGray5)
    var thumbColor = Color.white
    
    func makeBody(configuration: Self.Configuration) -> some View {
        HStack {
            Text(label)
            Spacer()
            Button(action: { configuration.isOn.toggle() } )
            {
                RoundedRectangle(cornerRadius: 16, style: .circular)
                    .fill(configuration.isOn ? onColor : offColor)
                    .frame(width: 50, height: 29)
                    .overlay(
                        Circle()
                            .fill(thumbColor)
                            .shadow(radius: 1, x: 0, y: 1)
                            .padding(1.5)
                            .offset(x: configuration.isOn ? 10 : -10))
                    .animation(Animation.easeInOut(duration: 0.1))
            }
        }
        .font(.title)
        .padding(.horizontal)
    }
}
Run Code Online (Sandbox Code Playgroud)

使用示例

Toggle("", isOn: $toggleState)
    .toggleStyle(
        ColoredToggleStyle(label: "My Colored Toggle",
                           onColor: .green,
                           offColor: .red,
                           thumbColor: Color(UIColor.systemTeal)))

Toggle("", isOn: $toggleState2)
    .toggleStyle(
        ColoredToggleStyle(label: "My Colored Toggle",
                           onColor: .purple))
Run Code Online (Sandbox Code Playgroud)

来自 SwiftUI 书籍

切换示例

  • 这确实是一项出色的工作,似乎是目前唯一可行的解​​决方案。谢谢! (3认同)
  • @MarkMoeykens 绝对出色的工作。我不知道`ToggleStyleConfiguration`是否有任何变化,但在HStack中,您可以直接使用`configuration.label`,而不是使用Text(label)。 (2认同)

Kar*_*sza 15

只需使用UIAppearanceAPI:

UISwitch.appearance().onTintColor = UIColor.blue
Run Code Online (Sandbox Code Playgroud)

UISwitch根据UIAppearance文档,它当然会默认更改 的所有实例的外观。

注意:从 Xcode 11 beta 5 开始测试。

  • 对于 iOS 14/Xcode 12 Beta 3,这似乎已被破坏。 (7认同)

Eve*_*ibe 10

SwiftUI 2.0(后 WWDC-2020)

使用新的 SwiftUI 增强功能,您可以使用.toggleStyle修饰符。

// Switch tinting

Toggle(isOn: $order.notifyWhenReady) {
    Text("Send notification when ready")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于 iOS14/iPadOS14/macOS11 及更高版本。


Geo*_*kov 7

您可以在 init() 中修改所有 UISwitch 对象的全局 onTintColor。

@State var enable_dhcp = true

init()
{
    UISwitch.appearance().onTintColor = .red
}

var body: some View
{
    Toggle("DHCP", isOn: $enable_dhcp)
}
Run Code Online (Sandbox Code Playgroud)

Toggle demo UIColor(red: 226.3/255.0, green: 37.6/255.0, blue: 40.7/255.0, alpha: 1.0)


Mo *_*ani 6

我还没有找到直接更改Toggle颜色的方法,但是拥有蓝色开关或任何其他自定义视图的另一种方法是创建您自己的自定义视图。要以最简单的形式制作自定义蓝色切换:

struct BlueToggle : UIViewRepresentable {
  func makeUIView(context: Context) -> UISwitch {
    UISwitch()
  }

  func updateUIView(_ uiView: UISwitch, context: Context) {
    uiView.onTintColor = UIColor.blue
  }
}

struct ContentView : View {
    var body: some View {
      BlueToggle()
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明


Spe*_*ton 5

构建@mohammad-reza-farahani 的解决方案,这是一种完全不妥协的方法,可以通过 SwiftUI 的实现协议获得 UISwitch 的可配置性。

首先将 a 包裹UISwitch在 a 中UIViewRepresentable并根据需要设置颜色:

final class CustomToggleWrapper: UIViewRepresentable {
    var isOn: Binding<Bool>

    init(isOn: Binding<Bool>) {
        self.isOn = isOn
    }

    func makeUIView(context: Context) -> UISwitch {
        UISwitch()
    }

    func updateUIView(_ uiView: UISwitch, context: Context) {
        // On color
        uiView.onTintColor = UIColor.blue
        // Off color
        uiView.tintColor = UIColor.red
        uiView.layer.cornerRadius = uiView.frame.height / 2
        uiView.backgroundColor = UIColor.red
        uiView.isOn = isOn.wrappedValue

        // Update bound boolean
        uiView.addTarget(self, action: #selector(switchIsChanged(_:)), for: .valueChanged)
    }

    @objc
    func switchIsChanged(_ sender: UISwitch) {
        isOn.wrappedValue = sender.isOn
    }
}
Run Code Online (Sandbox Code Playgroud)

其次,使用wrapped创建自定义切换样式UISwitch

struct CustomToggleStyle: ToggleStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        let toggle = CustomToggleWrapper(isOn: configuration.$isOn)

        return HStack {
            configuration.label
            Spacer()
            toggle
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Toggle像往常一样实施 a ,并应用您的CustomToggleStyle

struct TestView: View {
    @State private var isOn: Bool = true

    var body: some View {
        Toggle(
            isOn: $isOn
        ) {
            Text("Test: \(String(isOn))")
        }.toggleStyle(CustomToggleStyle()).padding()
    }
}
Run Code Online (Sandbox Code Playgroud)