Change color of UISwitch in “off” state

前端 未结 18 2582
忘掉有多难
忘掉有多难 2020-11-30 20:53

I\'ve learned that we can change the UISwitch button appearance in its \"on\" state, but is it also possible to change the color of the UISwitch in the \"off\" state?

相关标签:
18条回答
  • 2020-11-30 21:30

    You can use the tintColor property on the switch.

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

    Note this requires iOS 5+

    0 讨论(0)
  • 2020-11-30 21:31

    Swift IBDesignable

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

    set class in Identity inspector

    change color from Attributes inspector

    Output

    0 讨论(0)
  • 2020-11-30 21:31

    Swift 4 easiest and fastest way to get it in 3 steps:

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

    If you manually change the size of the switch (e.g., by using autolayout), you will have to update the switch.layer.cornerRadius too, e.g., by overriding layoutSubviews and after calling super updating the corner radius:

    override func layoutSubviews() {
        super.layoutSubviews()
        switchControl.layer.cornerRadius = switchControl.bounds.height / 2
    }
    
    0 讨论(0)
  • 2020-11-30 21:33

    Should you need other switches around your app, it might be also a good idea implementing @LongPham's code inside a custom class. As others have pointed out, for the "off" state you'll need to change the background colour as well, since the default is transparent.

    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
      }
    }
    
    0 讨论(0)
  • 2020-11-30 21:33

    More safe way in Swift 3 without magical 16pt values:

    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)
      }
    
    }
    
    0 讨论(0)
  • 2020-11-30 21:33

    XCode 11, Swift 4.2

    Starting with Matt's solution I added it to a custom, IBDesignable control. There is a timing issue in that didMoveToSuperview() is called before the offTintColor is set that needed to be handled.

    @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 讨论(0)
提交回复
热议问题