在“关闭”状态下更改UISwitch的颜色

128

我了解到我们可以改变UISwitch按钮在“打开”状态下的外观,但是否也可能改变UISwitch在“关闭”状态下的颜色?


你有使用过 tintColor 属性来改变颜色吗? - rishi
19个回答

190

我使用 #swift2 实现的解决方案:

let onColor  = _your_on_state_color
let offColor = _your_off_state_color

let mSwitch = UISwitch(frame: CGRect.zero)
mSwitch.on = true

/*For on state*/
mSwitch.onTintColor = onColor

/*For off state*/
mSwitch.tintColor = offColor
mSwitch.layer.cornerRadius = mSwitch.frame.height / 2.0
mSwitch.backgroundColor = offColor
mSwitch.clipsToBounds = true

结果:

在此输入图片描述


7
嘿,@longpham ,我只是想在半径代码上做出一点更改。以防万一高度发生变化,我会使用:mSwitch.layer.cornerRadius = mSwitch.frame.height/2 (我只是有点多虑)。 - Felipe
1
@Felipe Gringo 没问题。取决于您的用户界面。标准的 UISwitch 大小为 31pt。 - Long Pham

146

试着使用这个

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)进行了调整大小。但是在缩放视图中,这并不起作用。因为视图的图层没有被调整大小。我该如何使其正常工作? - AykutE
1
@aykutt 如果你想要缩放视图,可以使用以下代码:yourSwitch.layer.cornerRadius = yourSwitch.frame.height / 2 / scaleFactor - Hans Terje Bakke

49

您可以在开关上使用 tintColor 属性。

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

请注意,这需要 iOS 5 或更高版本。


4
在iOS7中设置tintColor会为我去掉"轮廓线"(在白色背景上针对白色着色)。 - Lukasz 'Severiaan' Grela

31

Swift可视化设计

import UIKit
@IBDesignable

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

在Identity inspector中设置类

输入图像描述

从Attributes inspector中更改颜色

输入图像描述

输出

输入图像描述


在Swift 3中它没有给出正确的输出。 - Ketan P
@KetanP,你能详细解释一下问题吗? - Afzaal Ahmad
1
运行Xcode 11.2.1,当运行应用程序时可以正常工作,但在IB中不显示颜色...无论如何,在部署到设备后它都可以正常工作。 - zumzum

24

这里有一个相当不错的技巧:您可以直接进入 UISwitch 的子视图,该子视图绘制其“关闭”背景,并更改其背景颜色。 在 iOS 13 中使用比在 iOS 12 中使用要好得多:

if #available(iOS 13.0, *) {
    self.sw.subviews.first?.subviews.first?.backgroundColor = .green
} else if #available(iOS 12.0, *) {
    self.sw.subviews.first?.subviews.first?.subviews.first?.backgroundColor = .green
}

在未来的iOS中,为了避免订阅期间出现崩溃,最好使用subviews.first?.而不是subviews[0]。 - Igor Palaguta
@IgorPalaguta 是的,好主意。我会进行更改。 - matt
@Igor Palaguta,这里有2个子视图,请您发布完整的代码。 - Naresh
使用这种技术需要注意一个小问题;由于某种原因,iOS 在应用程序从后台返回时喜欢将此颜色擦除回默认值。 - Peter Parker

12

图片描述
图片描述
适用于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
    }
}

你的解决方案无法适应暗模式下的颜色。 - ShadeToD

8

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

6

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

6

如果您需要在应用程序中使用其他开关,将@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
  }
}

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

如果您手动更改开关的大小(例如使用autolayout),则还必须更新switch.layer.cornerRadius,例如通过覆盖layoutSubviews并在调用super后更新圆角半径:
override func layoutSubviews() {
    super.layoutSubviews()
    switchControl.layer.cornerRadius = switchControl.bounds.height / 2
}

什么是integrationSwitch?而且在iOS 11中似乎无法工作。更改背景颜色会改变开关周围的一个更大的视图。 - Just a coder
@iOSCalendarViewOnMyProfile 抱歉,应该是 switchControl - Milan Nosáľ
1
@iOSCalendarViewOnMyProfile 应该改变背景颜色,而不是标记本身...在 iOS 的外观中,那总是默认的颜色.. - Milan Nosáľ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接