这是一个已知的 hack 来改变 tint 颜色UISegmentedControl
let sortedViews = listSegmentedControl.subviews.sorted( by: { $0.frame.origin.x < $1.frame.origin.x } )
for (index, view) in sortedViews.enumerated() {
if index == listSegmentedControl.selectedSegmentIndex {
view.tintColor = UIColor(patternImage: gradientImage)
} else {
view.tintColor = UIColor.gray //Whatever the color of non selected segment controller tab
}
}
虽然看起来像一个丑陋的黑客,但我已经使用了很长一段时间了,而且看起来相当简单。希望能帮助到你。
编辑:
这是你需要的朋友吗?

如果是,请让我知道,我会发布相同的代码。
编辑2:
正如 OP 在他的评论中提到的那样,他期望的输出与我在上图中显示的输出相同,并提供相同的代码。
免责声明:
正如rmaddy在下面的评论中所提到的,这是一个 hack,它使用了未记录的(尽管是完整的公共 API),但是一个众所周知的 hack 可以改变从 iOS 5 开始就存在的 UISegemntedControl 的色调颜色(这就是我记得的方式,让我知道我是否错了)
因此,请谨慎使用 answer ,在未来的 iOS 版本中,Apple可能会更改子视图的结构UISegemntedControl
并可能影响您的 O/P。我看不到的任何东西都不会导致崩溃,但可能会影响 O/P 在屏幕上的呈现方式。
我已经声明了一个变量,以便 GradientImage 只能生成一次,但它取决于您的实现以您想要的方式使用它
var gradientImage : UIImage! = nil
在ViewDidLoad
我初始化gradientImage
andUISegmentedControl
为
override func viewDidLoad() {
super.viewDidLoad()
gradientImage = gradient(size: segmentControl.frame.size, color: [UIColor.black, UIColor.red])!
//I have specified custom font need not necessarily be used
//Font color attribute is important though, usually `UISegementedControl` title takes color from tint color, because we might need a different color for text to highlight above gradient color am using custom font colors
let font = UIFont(name: "HelveticaNeue-Medium", size: 20)
segmentControl.setTitleTextAttributes([NSFontAttributeName : font!, NSForegroundColorAttributeName : UIColor.blue], for: .normal)
segmentControl.setTitleTextAttributes([NSForegroundColorAttributeName : UIColor.white], for: .selected)
//Set the border color and border to `UISegmentedControl` and also make it round corner
segmentControl.layer.borderColor = UIColor(patternImage: gradientImage).cgColor
segmentControl.layer.borderWidth = 2
segmentControl.layer.masksToBounds = true
segmentControl.layer.cornerRadius = 10
//In order to update the selected Segment tint and background color we need to call multiple statements every time selection changes hence I have moved it to the function and called it in viewDidLoad
updateGradientBackground()
}
最后 updateGradientBackground 函数定义与我在原始答案中发布的相同
fileprivate func updateGradientBackground() {
let sortedViews = segmentControl.subviews.sorted( by: { $0.frame.origin.x < $1.frame.origin.x } )
for (index, view) in sortedViews.enumerated() {
if index == segmentControl.selectedSegmentIndex {
//very important thing to notice here is because tint color was not honoring the `UIColor(patternImage` I rather used `backgroundColor` to create the effect and set clear color as clear color
view.backgroundColor = UIColor(patternImage: self.gradientImage)
view.tintColor = UIColor.clear
} else {
//very important thing to notice here is because tint color was not honoring the `UIColor(patternImage` I rather used `backgroundColor` to create the effect and set clear color as clear color
view.backgroundColor = UIColor.white //Whatever the color of non selected segment controller tab
view.tintColor = UIColor.clear
}
}
}
最后,在 UISegmentedControl 的 IBAction 中,只需调用
@IBAction func segmentControllerTapped(_ sender: UISegmentedControl) {
self.updateGradientBackground()
}
希望这可以帮助