"off"상태에서 UISwitch의 색상 변경


100

"on"상태에서 UISwitch 버튼 모양을 변경할 수 있다는 것을 배웠지 만 "off"상태에서 UISwitch의 색상을 변경할 수도 있습니까?


색상을 변경하기 위해 tintColor 속성을 사용 했습니까?
rishi 2010-04-27

답변:


136

# 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

결과:

여기에 이미지 설명 입력


6
안녕하세요, @longpham, 반경 코드를 약간 변경하겠습니다. 높이가 변경되는 경우 mSwitch.layer.cornerRadius = mSwitch.frame.height / 2 (나는 편집증입니다).
Felipe

@Felipe Gringo 문제 없습니다. UI에 따라 다릅니다. 표준 UISwitch은 31pt입니다.
Long Pham

133

이것을 사용해보십시오

yourSwitch.backgroundColor = [UIColor whiteColor];
youSwitch.layer.cornerRadius = 16.0;

@Barry Wyckoff 덕분입니다.


2
이것은 정답입니다 :) setTint는 "개요"색상도 변경하여 흰색 배경의 배경을 시각적으로 "숨 깁니다".
Lukasz 'Severiaan'Grela

2
배경은 직사각형 모양입니다.
Lukasz 'Severiaan'Grela

내 스위치는 CGAffineTransformMakeScale(0.80, 0.80). 그리고 이것은 배율보기에서 작동하지 않습니다. 보기의 레이어 크기가 조정되지 않기 때문입니다. 이 작업을 어떻게 할 수 있습니까?
aykutt 2015

1
확장 뷰에 대한 @aykutt 당신은 yourSwitch.layer.cornerRadius = yourSwitch.frame.height / 2 / scaleFactor와 사용할 수 있습니다
한스 테르 예 Bakke

37

tintColor스위치 의 속성을 사용할 수 있습니다 .

switch.tintColor = [UIColor redColor]; // the "off" color
switch.onTintColor = [UIColor greenColor]; // the "on" color

iOS 5 이상이 필요합니다.


3
iOS7에서 tintColor를 설정하면 "개요"가 제거됩니다 (흰색 배경에 흰색 색조).
Lukasz 'Severiaan'Grela

28

스위프트 IB

import UIKit
@IBDesignable

class UISwitchCustom: UISwitch {
    @IBInspectable var OffTint: UIColor? {
        didSet {
            self.tintColor = OffTint
            self.layer.cornerRadius = 16
            self.backgroundColor = OffTint
        }
    }
}

Identity inspector에서 클래스 설정

여기에 이미지 설명 입력

속성 관리자에서 색상 변경

여기에 이미지 설명 입력

산출

여기에 이미지 설명 입력


그것은 신속한 3에 넣어 적절한 아웃을 제공하지 않습니다
Ketan P

@KetanP 문제를 더 자세히 설명해 주시겠습니까?
Afzaal Ahmad

Xcode 11.2.1을 실행하면 앱을 실행할 때 작동하지만 IB에 색상이 표시되지 않습니다 .... 어쨌든 장치에 배포 할 때 작동합니다.
zumzum

11

여기에 꽤 좋은 트릭이 있습니다. "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
}

6

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
        }
    }
}

5

Swift 4+에서 :

off 상태:

switch.tintColor = UIColor.blue

on 상태:

switch.onTintColor = UIColor.red

3
iOS 13 이상에서는 작동하지 않으며 설정 tintColor이 적용되지 않습니다.
Eric

5

스위프트 5 :

import UIKit

extension UISwitch {    

    func set(offTint color: UIColor ) {
        let minSide = min(bounds.size.height, bounds.size.width)
        layer.cornerRadius = minSide / 2
        backgroundColor = color
        tintColor = color
    }
}

4

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
}

integrationSwitch 란 무엇입니까? 또한, 스위치 주변에 큰 찾고보기를 변경 배경 색상을 변경 아이폰 OS 11에서 제대로 작동 나던
FlowUI합니다. SimpleUITesting.com 2018 년

@iOSCalendarViewOnMyProfile 죄송합니다.이게되어야합니다switchControl
Milan Nosáľ

1
아이폰 OS 모양에 ..하지 총알 자체 배경색을 변경하고 항상 기본 색상입니다 .. 느낌을 해야하는 @iOSCalendarViewOnMyProfile
밀라노 Nosáľ

4

앱 주변에 다른 스위치가 필요한 경우 사용자 정의 클래스 내에서 @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
  }
}

3

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),
    ])
}

[하지만 이제 내 다른 대답을 참조하십시오 .]


2

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
}

다른 답변보다 간단 해 보입니다. 도움이 되었기를 바랍니다.


아름답고 간단한 대답, 대단히 감사합니다. +1
mAc

1

마법의 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)
  }

}

1

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
        }
    }

1

여기에 이미지 설명 입력
여기에 이미지 설명 입력
100 % IOS 13.0 및 Swift 5.0 스위치 작동 중 두 상태 색상이 동일하게 설정 됨 # ios13 #swift # swift5

@IBOutlet weak var switchProfile: UISwitch!{
    didSet{
        switchProfile.onTintColor = .red
        switchProfile.tintColor = .red
        switchProfile.subviews[0].subviews[0].backgroundColor = .red
    }
}

0

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
    }

}

0

코드 또는 스토리 보드를 사용하여 프로젝트의 모든 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

0

마침내 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를 사용했습니다. 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.