Eu aprendi que podemos mudar a aparência do botão UISwitch em seu estado "ligado", mas também é possível mudar a cor do UISwitch no estado "desligado"?
Ei, @longpham, gostaria apenas de fazer uma pequena mudança no código do raio. Caso a altura mude, eu usaria: mSwitch.layer.cornerRadius = mSwitch.frame.height / 2 (sou apenas paranóico).
Felipe
@Felipe Gringo Não tem problema. Depende da sua IU. O padrão UISwitché 31pt.
ESTA é a resposta correta :) setTint também altera a cor do "contorno", que "esconde" visualmente o fundo no fundo branco.
Lukasz 'Severiaan' Grela
2
Esteja ciente de que o fundo tem uma forma retangular.
Lukasz 'Severiaan' Grela
Meu switch é redimensionado com CGAffineTransformMakeScale(0.80, 0.80). E isso não está funcionando com visualização em escala. Porque a camada da vista não é redimensionada. Como posso fazer isso funcionar?
aykutt de
1
@aykutt para visualização em escala, você pode usar yourSwitch.layer.cornerRadius = yourSwitch.frame.height / 2 / scaleFactor
Hans Terje Bakke
37
Você pode usar a tintColorpropriedade no switch.
switch.tintColor =[UIColor redColor];// the "off" colorswitch.onTintColor =[UIColor greenColor];// the "on" color
@KetanP você pode explicar o problema com mais detalhes?
Afzaal Ahmad de
executando o Xcode 11.2.1, funciona ao executar o aplicativo, mas não mostra a cor no IB .... de qualquer maneira, funciona quando implantado no dispositivo.
zumzum de
10
Aqui está um truque muito bom: você pode simplesmente acessar a subvisão do UISwitch que desenha seu fundo "desligado" e alterar sua cor de fundo. Isso funciona muito melhor no iOS 13 do que no iOS 12:
A melhor maneira de gerenciar a cor de fundo e tamanho do UISwitch
Por enquanto, é o código Swift 2.3
importFoundationimportUIKit@IBDesignableclassUICustomSwitch:UISwitch{@IBInspectablevarOnColor:UIColor!=UIColor.blueColor()@IBInspectablevarOffColor:UIColor!=UIColor.grayColor()@IBInspectablevarScale:CGFloat!=1.0override init(frame:CGRect){super.init(frame: frame)self.setUpCustomUserInterface()}
required init?(coder aDecoder:NSCoder){super.init(coder: aDecoder)self.setUpCustomUserInterface()}
func setUpCustomUserInterface(){//clip the background colorself.layer.cornerRadius =16self.layer.masksToBounds =true//Scale down to make it smaller in lookself.transform =CGAffineTransformMakeScale(self.Scale,self.Scale);//add target to get user interation to update user-interface accordinglyself.addTarget(self, action:#selector(UICustomSwitch.updateUI), forControlEvents: UIControlEvents.ValueChanged)//set onTintColor : is necessary to make it coloredself.onTintColor =self.OnColor//setup to initial stateself.updateUI()}//to track programatic updateoverride func setOn(on:Bool, animated:Bool){super.setOn(on, animated:true)
updateUI()}//Update user-interface according to on/off state
func updateUI(){ifself.on ==true{self.backgroundColor =self.OnColor}else{self.backgroundColor =self.OffColor}}}
Swift 4 a maneira mais fácil e rápida de obtê-lo em 3 etapas:
// background color is the color of the background of the switch
switchControl.backgroundColor =UIColor.white.withAlphaComponent(0.9)// tint color is the color of the border when the switch is off, use// clear if you want it the same as the background, or different otherwise
switchControl.tintColor =UIColor.clear// and make sure that the background color will stay in border of the switch
switchControl.layer.cornerRadius = switchControl.bounds.height /2
Se você alterar manualmente o tamanho do switch (por exemplo, usando autolayout), você terá que atualizar o switch.layer.cornerRadiustambém, por exemplo, substituindo layoutSubviewse depois de chamar a superatualização do raio do canto:
@iOSCalendarViewOnMyProfile é suposto mudar a cor de fundo, não o marcador em si .. na aparência do iOS esta é sempre a cor padrão ..
Milan Nosáľ
4
Se você precisar de outras opções em seu aplicativo, também pode ser uma boa ideia implementar o código de @LongPham dentro de uma classe personalizada. Como outros apontaram, para o estado "desligado", você também precisará alterar a cor de fundo, já que o padrão é transparente.
O UISwitch offTintColoré transparente, então tudo o que está atrás do switch aparece. Portanto, em vez de mascarar a cor de fundo, é suficiente desenhar uma imagem em forma de switch por trás do switch (esta implementação assume que o switch está posicionado por autolayout):
func putColor(_ color:UIColor, behindSwitch sw:UISwitch){
guard sw.superview !=nilelse{return}let onswitch =UISwitch()
onswitch.isOn =truelet r =UIGraphicsImageRenderer(bounds:sw.bounds)let im = r.image { ctx in
onswitch.layer.render(in: ctx.cgContext)}.withRenderingMode(.alwaysTemplate)let iv =UIImageView(image:im)
iv.tintColor = color
sw.superview!.insertSubview(iv, belowSubview: sw)
iv.translatesAutoresizingMaskIntoConstraints =falseNSLayoutConstraint.activate([
iv.topAnchor.constraint(equalTo: sw.topAnchor),
iv.bottomAnchor.constraint(equalTo: sw.bottomAnchor),
iv.leadingAnchor.constraint(equalTo: sw.leadingAnchor),
iv.trailingAnchor.constraint(equalTo: sw.trailingAnchor),])}
Esta é a maneira mais simples que encontrei de definir a cor de estado desativado do UISwitch com uma linha de código . Escrever isso aqui, já que esta página é o que surgiu primeiro quando eu estava procurando e as outras respostas não ajudaram.
Isso se eu quiser definir o estado desligado como vermelho e puder ser adicionado à função viewDidLoad ():
Observação - o que isso está realmente fazendo é definir a cor de fundo do switch. Isso pode influenciar a cor do interruptor no estado ligado também (embora para mim isso não fosse um problema, pois eu queria que o estado ligado e desligado fossem da mesma cor).
Uma solução para isso:
Simplesmente amarre as cores com uma declaração 'if else' dentro de sua IBAction. Se a chave estiver desligada, pinte o fundo de vermelho. Se a chave estiver ligada, deixe o plano de fundo claro para que a cor "ligada" escolhida seja exibida corretamente.
Isso vai dentro do switch IBAction.
if yourSwitch.isOn ==false{
yourSwitch.subviews[0].subviews[0].backgroundColor =UIColor.red
}else{
yourSwitch.subviews[0].subviews[0].backgroundColor =UIColor.clear
}
Eu encontrei um comportamento em que, após o app retomar do fundo, o fundo do switch voltava a ficar claro. Para solucionar esse problema, simplesmente adicionei o código a seguir para definir a cor sempre que o aplicativo vier para o primeiro plano:
Eu não prefiro usar subViews, porque você nunca sabe quando a apple vai mudar a hierarquia.
então eu uso a vista de máscara.
funciona com iOS 12, iOS 13
private lazy var settingSwitch:UISwitch={let swt:UISwitch=UISwitch()// set border color when isOn is false
swt.tintColor =.cloudyBlueTwo
// set border color when isOn is true
swt.onTintColor =.greenishTeal
// set background color when isOn is false
swt.backgroundColor =.cloudyBlueTwo
// create a mask view to clip background over the size you expected.let maskView =UIView(frame: swt.frame)
maskView.backgroundColor =.red
maskView.layer.cornerRadius = swt.frame.height /2
maskView.clipsToBounds =true
swt.mask = maskView
// set the scale to your expectation, here is around height: 34, width: 21.let scale:CGFloat=2/3
swt.transform =CGAffineTransform(scaleX: scale, y: scale)
swt.addTarget(self, action:#selector(switchOnChange(_:)), for: .valueChanged)return swt
}()@objc
func switchOnChange(_ sender:UISwitch){if sender.isOn {// set background color when isOn is true
sender.backgroundColor =.greenishTeal
}else{// set background color when isOn is false
sender.backgroundColor =.cloudyBlueTwo
}}
Começando com a solução de Matt, adicionei-o a um controle IBDesignable personalizado. Há um problema de tempo em que didMoveToSuperview()é chamado antes de offTintColorser definido que precisava ser tratado.
#import "UISwitch+SAHelper.h"@implementationUISwitch(SAHelper)@dynamic offTint;-(void)setOffTint:(UIColor*)offTint {self.tintColor = offTint;//comment this line to hide border in off stateself.layer.cornerRadius =16;self.backgroundColor = offTint;}@end
Respostas:
Minha solução com # swift2:
Resultado:
fonte
UISwitch
é 31pt.Tente usar isto
Todos graças a @Barry Wyckoff.
fonte
CGAffineTransformMakeScale(0.80, 0.80)
. E isso não está funcionando com visualização em escala. Porque a camada da vista não é redimensionada. Como posso fazer isso funcionar?Você pode usar a
tintColor
propriedade no switch.Observe que isso requer iOS 5+
fonte
Swift IBDesignable
definir classe no inspetor de identidade
mude a cor no inspetor de atributos
Resultado
fonte
Aqui está um truque muito bom: você pode simplesmente acessar a subvisão do UISwitch que desenha seu fundo "desligado" e alterar sua cor de fundo. Isso funciona muito melhor no iOS 13 do que no iOS 12:
fonte
Por enquanto, é o código Swift 2.3
fonte
Em Swift 4+:
off
Estado:on
Estado:fonte
tintColor
não tem efeito.Swift 5:
fonte
Swift 4 a maneira mais fácil e rápida de obtê-lo em 3 etapas:
Se você alterar manualmente o tamanho do switch (por exemplo, usando autolayout), você terá que atualizar o
switch.layer.cornerRadius
também, por exemplo, substituindolayoutSubviews
e depois de chamar a superatualização do raio do canto:fonte
switchControl
Se você precisar de outras opções em seu aplicativo, também pode ser uma boa ideia implementar o código de @LongPham dentro de uma classe personalizada. Como outros apontaram, para o estado "desligado", você também precisará alterar a cor de fundo, já que o padrão é transparente.
fonte
O UISwitch
offTintColor
é transparente, então tudo o que está atrás do switch aparece. Portanto, em vez de mascarar a cor de fundo, é suficiente desenhar uma imagem em forma de switch por trás do switch (esta implementação assume que o switch está posicionado por autolayout):[Mas veja agora minha outra resposta .]
fonte
2020 a partir do Xcode 11.3.1 e Swift 5
Esta é a maneira mais simples que encontrei de definir a cor de estado desativado do UISwitch com uma linha de código . Escrever isso aqui, já que esta página é o que surgiu primeiro quando eu estava procurando e as outras respostas não ajudaram.
Isso se eu quiser definir o estado desligado como vermelho e puder ser adicionado à função viewDidLoad ():
Observação - o que isso está realmente fazendo é definir a cor de fundo do switch. Isso pode influenciar a cor do interruptor no estado ligado também (embora para mim isso não fosse um problema, pois eu queria que o estado ligado e desligado fossem da mesma cor).
Uma solução para isso:
Simplesmente amarre as cores com uma declaração 'if else' dentro de sua IBAction. Se a chave estiver desligada, pinte o fundo de vermelho. Se a chave estiver ligada, deixe o plano de fundo claro para que a cor "ligada" escolhida seja exibida corretamente.
Isso vai dentro do switch IBAction.
Eu encontrei um comportamento em que, após o app retomar do fundo, o fundo do switch voltava a ficar claro. Para solucionar esse problema, simplesmente adicionei o código a seguir para definir a cor sempre que o aplicativo vier para o primeiro plano:
Parece mais simples do que as outras respostas. Espero que ajude!
fonte
Maneira mais segura no Swift 3 sem valores mágicos de 16pt:
fonte
XCode 11, Swift 5
Eu não prefiro usar subViews, porque você nunca sabe quando a apple vai mudar a hierarquia.
então eu uso a vista de máscara.
funciona com iOS 12, iOS 13
fonte
Trabalhando 100% IOS 13.0 e Swift 5.0 alternar ambos os estados de cor definida da mesma forma # ios13 #swift # swift5
fonte
XCode 11, Swift 4.2
Começando com a solução de Matt, adicionei-o a um controle IBDesignable personalizado. Há um problema de tempo em que
didMoveToSuperview()
é chamado antes deoffTintColor
ser definido que precisava ser tratado.fonte
categoria c de objetivo para usar em qualquer UISwitch em projeto usando código ou storyboard:
implementação
fonte
Finalmente usei transform e layer.cornerRadius também. Mas acrescentei tradução a ele para ser o centro.
E eu usei backgroundColor e tintColor no designer. Espero que ajude.
fonte