"on"상태에서 UISwitch 버튼 모양을 변경할 수 있다는 것을 배웠지 만 "off"상태에서 UISwitch의 색상을 변경할 수도 있습니까?
"on"상태에서 UISwitch 버튼 모양을 변경할 수 있다는 것을 배웠지 만 "off"상태에서 UISwitch의 색상을 변경할 수도 있습니까?
답변:
# swift2를 사용한 내 솔루션 :
let onColor = _your_on_state_color
let offColor = _your_off_state_color
let mSwitch = UISwitch(frame: CGRectZero)
mSwitch.on = true
/*For on state*/
mSwitch.onTintColor = onColor
/*For off state*/
mSwitch.tintColor = offColor
mSwitch.layer.cornerRadius = mSwitch.frame.height / 2
mSwitch.backgroundColor = offColor
결과:
UISwitch
은 31pt입니다.
이것을 사용해보십시오
yourSwitch.backgroundColor = [UIColor whiteColor];
youSwitch.layer.cornerRadius = 16.0;
@Barry Wyckoff 덕분입니다.
CGAffineTransformMakeScale(0.80, 0.80)
. 그리고 이것은 배율보기에서 작동하지 않습니다. 보기의 레이어 크기가 조정되지 않기 때문입니다. 이 작업을 어떻게 할 수 있습니까?
tintColor
스위치 의 속성을 사용할 수 있습니다 .
switch.tintColor = [UIColor redColor]; // the "off" color
switch.onTintColor = [UIColor greenColor]; // the "on" color
iOS 5 이상이 필요합니다.
여기에 꽤 좋은 트릭이 있습니다. "off"배경을 그리는 UISwitch의 하위 뷰로 바로 이동하여 배경 색상을 변경할 수 있습니다. 이것은 iOS 12에서보다 iOS 13에서 훨씬 더 잘 작동합니다.
if #available(iOS 13.0, *) {
self.sw.subviews[0].subviews[0].backgroundColor = .green
} else if #available(iOS 12.0, *) {
self.sw.subviews[0].subviews[0].subviews[0].backgroundColor = .green
}
UISwitch의 배경색 및 크기를 관리하는 가장 좋은 방법
지금은 Swift 2.3 코드입니다.
import Foundation
import UIKit
@IBDesignable
class UICustomSwitch : UISwitch {
@IBInspectable var OnColor : UIColor! = UIColor.blueColor()
@IBInspectable var OffColor : UIColor! = UIColor.grayColor()
@IBInspectable var Scale : CGFloat! = 1.0
override 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 color
self.layer.cornerRadius = 16
self.layer.masksToBounds = true
//Scale down to make it smaller in look
self.transform = CGAffineTransformMakeScale(self.Scale, self.Scale);
//add target to get user interation to update user-interface accordingly
self.addTarget(self, action: #selector(UICustomSwitch.updateUI), forControlEvents: UIControlEvents.ValueChanged)
//set onTintColor : is necessary to make it colored
self.onTintColor = self.OnColor
//setup to initial state
self.updateUI()
}
//to track programatic update
override func setOn(on: Bool, animated: Bool) {
super.setOn(on, animated: true)
updateUI()
}
//Update user-interface according to on/off state
func updateUI() {
if self.on == true {
self.backgroundColor = self.OnColor
}
else {
self.backgroundColor = self.OffColor
}
}
}
Swift 4 를 3 단계로 얻는 가장 쉽고 빠른 방법 :
// 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
스위치의 크기를 수동으로 변경하는 경우 (예 : 자동 레이아웃을 사용하여) switch.layer.cornerRadius
, 예를 들어, layoutSubviews
코너 반경을 수퍼 업데이트를 호출 한 후 재정 의하여 업데이트해야합니다.
override func layoutSubviews() {
super.layoutSubviews()
switchControl.layer.cornerRadius = switchControl.bounds.height / 2
}
switchControl
앱 주변에 다른 스위치가 필요한 경우 사용자 정의 클래스 내에서 @LongPham의 코드를 구현하는 것도 좋은 생각 일 수 있습니다. 다른 사람들이 지적했듯이 "꺼짐"상태의 경우 기본값이 투명하기 때문에 배경색도 변경해야합니다.
class MySwitch: UISwitch {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Setting "on" state colour
self.onTintColor = UIColor.green
// Setting "off" state colour
self.tintColor = UIColor.red
self.layer.cornerRadius = self.frame.height / 2
self.backgroundColor = UIColor.red
}
}
UISwitch offTintColor
는 투명하므로 스위치 뒤에있는 모든 것이 표시됩니다. 따라서 배경색을 마스킹하는 대신 스위치 뒤에 스위치 모양의 이미지를 그리는 것으로 충분합니다 (이 구현에서는 스위치가 자동 레이아웃에 의해 배치된다고 가정합니다).
func putColor(_ color: UIColor, behindSwitch sw: UISwitch) {
guard sw.superview != nil else {return}
let onswitch = UISwitch()
onswitch.isOn = true
let 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 = false
NSLayoutConstraint.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),
])
}
[하지만 이제 내 다른 대답을 참조하십시오 .]
2020 Xcode 11.3.1 및 Swift 5 기준
다음 은 코드 한 줄로 UISwitch 오프 상태 색상을 설정하는 가장 간단한 방법 입니다. 이 페이지는 내가보고있을 때 처음 나온 것이고 다른 답변은 도움이되지 않았기 때문에 여기에 작성하십시오.
이것은 꺼짐 상태를 빨간색으로 설정하고 viewDidLoad () 함수에 추가 할 수있는 경우입니다.
yourSwitchName.subviews[0].subviews[0].backgroundColor = UIColor.red
참고-이것이 실제로하는 일은 스위치의 배경색을 설정하는 것입니다. 이것은 켜짐 상태의 스위치 색상에도 영향을 줄 수 있습니다 (나는 켜짐과 꺼짐 상태가 같은 색상 이길 원했기 때문에 문제가되지 않았습니다).
이에 대한 해결책 :
IBAction 내부의 'if else'문으로 색상을 연결하기 만하면됩니다. 스위치가 꺼져 있으면 배경을 빨간색으로 지정하십시오. 스위치가 켜져 있으면, 배경이 떠나 취소 하여 제대로 표시됩니다 색상 '에'선택 있도록.
이것은 스위치 IBAction 내부 에 있습니다.
if yourSwitch.isOn == false {
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.red
} else {
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.clear
}
앱이 백그라운드에서 다시 시작되면 스위치 백그라운드가 지워지는 동작을 발견했습니다. 이 문제를 해결하기 위해 다음 코드를 추가하여 앱이 포 그라운드에 올 때마다 색상을 설정했습니다.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillEnterForeground(_:)),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}
@objc func applicationWillEnterForeground(_ notification: NSNotification) {
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.red
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.red
}
다른 답변보다 간단 해 보입니다. 도움이 되었기를 바랍니다.
마법의 16pt 값없이 Swift 3 에서 더 안전한 방법 :
class ColoredBackgroundSwitch: UISwitch {
var offTintColor: UIColor {
get {
return backgroundColor ?? UIColor.clear
}
set {
backgroundColor = newValue
}
}
override func layoutSubviews() {
super.layoutSubviews()
let minSide = min(frame.size.height, frame.size.width)
layer.cornerRadius = ceil(minSide / 2)
}
}
XCode 11, Swift 5
나는 subViews를 사용하는 것을 선호하지 않습니다. 왜냐하면 당신은 애플이 언제 계층 구조를 바꿀지 알 수 없기 때문입니다.
그래서 대신 마스크 뷰를 사용합니다.
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
}
}
XCode 11, Swift 4.2
Matt의 솔루션으로 시작 하여 사용자 지정 IBDesignable 컨트롤에 추가했습니다. 처리해야하는가 설정 didMoveToSuperview()
되기 전에 호출 되는 타이밍 문제 offTintColor
가 있습니다.
@IBDesignable public class UISwitchCustom: UISwitch {
var switchMask: UIImageView?
private var observers = [NSKeyValueObservation]()
@IBInspectable dynamic var offTintColor : UIColor! = UIColor.gray {
didSet {
switchMask?.tintColor = offTintColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initializeObservers()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initializeObservers()
}
private func initializeObservers() {
observers.append(observe(\.isHidden, options: [.initial]) {(model, change) in
self.switchMask?.isHidden = self.isHidden
})
}
override public func didMoveToSuperview() {
addOffColorMask(offTintColor)
super.didMoveToSuperview()
}
private func addOffColorMask(_ color: UIColor) {
guard self.superview != nil else {return}
let onswitch = UISwitch()
onswitch.isOn = true
let r = UIGraphicsImageRenderer(bounds:self.bounds)
let im = r.image { ctx in
onswitch.layer.render(in: ctx.cgContext)
}.withRenderingMode(.alwaysTemplate)
let iv = UIImageView(image:im)
iv.tintColor = color
self.superview!.insertSubview(iv, belowSubview: self)
iv.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
iv.topAnchor.constraint(equalTo: self.topAnchor),
iv.bottomAnchor.constraint(equalTo: self.bottomAnchor),
iv.leadingAnchor.constraint(equalTo: self.leadingAnchor),
iv.trailingAnchor.constraint(equalTo: self.trailingAnchor),
])
switchMask = iv
switchMask?.isHidden = self.isHidden
}
}
코드 또는 스토리 보드를 사용하여 프로젝트의 모든 UISwitch에서 사용할 객관적인 c 범주 :
#import <UIKit/UIKit.h>
@interface UISwitch (SAHelper)
@property (nonatomic) IBInspectable UIColor *offTint;
@end
이행
#import "UISwitch+SAHelper.h"
@implementation UISwitch (SAHelper)
@dynamic offTint;
- (void)setOffTint:(UIColor *)offTint {
self.tintColor = offTint; //comment this line to hide border in off state
self.layer.cornerRadius = 16;
self.backgroundColor = offTint;
}
@end
마침내 transform과 layer.cornerRadius도 사용했습니다. 하지만 중심이되도록 번역을 추가했습니다.
private func setSwitchSize() {
let iosSwitchSize = switchBlockAction.bounds.size
let requiredSwitchSize = ...
let transform = CGAffineTransform(a: requiredSwitchSize.width / iosSwitchSize.width, b: 0,
c: 0, d: requiredSwitchSize.height / iosSwitchSize.height,
tx: (requiredSwitchSize.width - iosSwitchSize.width) / 2.0,
ty: (requiredSwitchSize.height - iosSwitchSize.height) / 2.0)
switchBlockAction.layer.cornerRadius = iosSwitchSize.height / 2.0
switchBlockAction.transform = transform
}
그리고 디자이너에서 backgroundColor와 tintColor를 사용했습니다. 도움이되기를 바랍니다.