UISwitch开启状态下修改背景色并保留灰色边框的实现方法
解决UISwitch On状态保留灰色边框并修改背景色的问题
当然有办法啦!默认的onTintColor确实会把开关的背景和边框一起改成目标颜色,要实现你要的效果,咱们可以通过自定义UISwitch子类的方式来调整内部视图的样式,下面是具体的实现步骤:
方法一:自定义UISwitch子类(推荐,无私有API风险)
通过重写setOn(_:animated:)和layoutSubviews方法,在开关状态切换或布局变化时,手动调整内部背景视图的颜色和边框:
import UIKit class CustomBorderSwitch: UISwitch { // 自定义你需要的颜色 private let onBackgroundColor = UIColor(red: 0.2, green: 0.8, blue: 0.2, alpha: 1.0) // 示例绿色 private let borderColor = UIColor.gray override func setOn(_ on: Bool, animated: Bool) { super.setOn(on, animated: animated) updateSwitchAppearance() } override func layoutSubviews() { super.layoutSubviews() // 布局更新后重新调整样式,避免布局变化导致样式重置 updateSwitchAppearance() } private func updateSwitchAppearance() { // 遍历内部子视图,定位到背景容器 for subview in subviews { for subsubview in subview.subviews { guard let backgroundImageView = subsubview as? UIImageView else { continue } if isOn { backgroundImageView.backgroundColor = onBackgroundColor backgroundImageView.layer.borderColor = borderColor.cgColor backgroundImageView.layer.borderWidth = 1.0 // 保持圆角和开关本身一致 backgroundImageView.layer.cornerRadius = backgroundImageView.frame.height / 2 } else { // 恢复Off状态的透明背景与无边框 backgroundImageView.backgroundColor = .clear backgroundImageView.layer.borderColor = UIColor.clear.cgColor backgroundImageView.layer.borderWidth = 0.0 } break } } } }
使用方式
不管是代码创建还是Storyboard拖拽,直接替换成这个自定义类就行:
// 代码创建示例 let customSwitch = CustomBorderSwitch(frame: CGRect(x: 50, y: 100, width: 0, height: 0)) customSwitch.addTarget(self, action: #selector(switchValueChanged(_:)), for: .valueChanged) view.addSubview(customSwitch)
注意事项
- 这种方法依赖UISwitch的内部视图层级,目前在iOS 15+系统上测试稳定,但苹果未来可能调整内部结构,导致代码失效。如果需要长期稳定的方案,建议完全自定义绘制Switch控件。
- 如果你不想自定义子类,也可以在开关的
valueChanged回调事件中执行类似的视图遍历逻辑,但代码复用性会差一些。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

