J'ai implémenté une bascule après avoir suivi Apple tutoriel sur la saisie utilisateur . Actuellement, cela ressemble à ceci:
Voici le code qui produit cette interface utilisateur:
NavigationView {
List {
Toggle(isOn: $showFavoritesOnly) {
Text("Show Favorites only")
}
}
}
Maintenant, j'aimerais que le Toggle
sur - la couleur soit bleue au lieu de verte.
J'ai essayé:
Toggle(isOn: $showFavoritesOnly) {
Text("Show Favorites only")
}
.accentColor(.blue)
.foregroundColor(.blue)
.background(Color.blue)
Rien de tout cela n'a fonctionné et je n'ai pas pu trouver d'autres modificateurs, tels que tintColor
.
Comment changer la couleur d'un Toggle
?
J'ai créé un nouveau ToggleStyle pour changer les trois couleurs du Toggle (on color, off color et the 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)
}
}
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))
Utilisez simplement les API UIAppearance
:
UISwitch.appearance().onTintColor = UIColor.blue
Il va bien sûr par défaut changer l'apparence de toutes les instances de UISwitch
, selon la documentation de UIAppearance
.
REMARQUE: testé à partir de Xcode 11 beta 5.
Je n'ai pas encore trouvé de moyen de changer directement une couleur Toggle
mais une autre façon d'avoir un interrupteur bleu ou toute autre vue personnalisée, est de créer une vue personnalisée de votre choix. Pour créer une bascule bleue personnalisée dans sa forme la plus simple:
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()
}
}
Résultat:
En s'appuyant sur la solution de @ mohammad-reza-farahani, voici une approche sans compromis pour obtenir la configurabilité d'UISwitch avec les protocoles d'implémentation de SwiftUI.
Enveloppez d'abord un UISwitch
dans un UIViewRepresentable
et définissez les couleurs comme vous le souhaitez:
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
}
}
Deuxièmement, créez un style de bascule personnalisé en utilisant le UISwitch
enveloppé:
struct CustomToggleStyle: ToggleStyle {
func makeBody(configuration: Self.Configuration) -> some View {
let toggle = CustomToggleWrapper(isOn: configuration.$isOn)
return HStack {
configuration.label
Spacer()
toggle
}
}
}
Implémentez un Toggle
comme vous le feriez normalement et appliquez votre CustomToggleStyle
:
struct TestView: View {
@State private var isOn: Bool = true
var body: some View {
Toggle(
isOn: $isOn
) {
Text("Test: \(String(isOn))")
}.toggleStyle(CustomToggleStyle()).padding()
}
}
Karol Kulesza et George Valkov ont fourni une solution très facile à mettre en œuvre. Je voulais juste ajouter que vous pouvez également placer le code ci-dessous dans la méthode didFinishLaunching du délégué de l'application.
UISwitch.appearance().onTintColor = .blue
Vous pouvez également créer des configurations d'apparence plus spécifiques avec
appearance(whenContainedInInstancesOf:)
Voir https://www.hackingwithswift.com/example-code/uikit/what-is-the-uiappearance-proxy
Cette https://stackoverflow.com/a/56480720/5941807 (pour l'instant avec Xcode 11 beta 6) est une solution. Pour basculer entre les options d'une manière rapide, utilisez le booléen au lieu de if/else:
showFavoritesOnly ? .red : .blue
pour le premier plan:
Toggle(isOn: $showGreeting) {
Text("Show Favorites only").foregroundColor(showFavoritesOnly ? .blue : .gray)
}
pour teinte:
uiView.onTintColor = showFavoritesOnly ? UIColor.blue : UIColor.gray
En plus pour les couleurs personnalisées: https://stackoverflow.com/a/57744208/5941807
Comme la question d'origine était juste de changer la bascule sur la couleur et non la personnalisation visuelle complète de Toggle
, je pense que quelque chose comme ça ferait:
import SwiftUI
struct CustomToggle: UIViewRepresentable {
@Binding var isOn: Bool
func makeCoordinator() -> CustomToggle.Coordinator {
Coordinator(isOn: $isOn)
}
func makeUIView(context: Context) -> UISwitch {
let view = UISwitch()
view.onTintColor = UIColor.red
view.addTarget(context.coordinator, action: #selector(Coordinator.switchIsChanged(_:)), for: .valueChanged)
return view
}
func updateUIView(_ uiView: UISwitch, context: Context) {
uiView.isOn = isOn
}
class Coordinator: NSObject {
@Binding private var isOn: Bool
init(isOn: Binding<Bool>) {
_isOn = isOn
}
@objc func switchIsChanged(_ sender: UISwitch) {
_isOn.wrappedValue = sender.isOn
}
}
}
// MARK: - Previews
struct CustomToggle_Previews: PreviewProvider {
static var previews: some View {
ViewWrapper()
}
struct ViewWrapper: View {
@State(initialValue: false) var isOn: Bool
var body: some View {
CustomToggle(isOn: $isOn)
.previewLayout(.fixed(width: 100, height: 100))
}
}
}