如何在 iOS 13 中将 UISegmentedControl 的背景颜色设置为白色
How to set backgroundColor of UISegmentedControl to white in iOS 13
iOS 13 对 UISegmentedControl 进行了一些更改,包括切换选定段时非常漂亮的动画。但是我注意到它没有正确显示 backgroundColor
属性,它似乎总是带有一点色彩。
我已经看到回答如何设置 selectedSegmentTintColor
之类的问题,但我正在努力将 backgroundColor
设置为 .white
,无论我做什么即使没有应用 tintColor
或类似设置,也总是显示出一点灰色。将 backgroundColor
设置为其他颜色会显示相同的行为,但最明显的是白色。更神秘的是,虽然这种差异出现在 iOS 13 模拟器和物理设备 运行 iOS 13 上,但可视化调试器(在 XCode 11 GM2 中)确实不显示这种差异!
这里有几个屏幕截图显示,即使 UISegmentedControl
的 backgroundColor
设置为与其后面显示的视图的 backgroundColor
相同,它们也略有不同。
设备运行iOS13(白色背景色)
与 Visual Debugger 中显示的相同 view/code(白色背景颜色)
设备运行iOS13(蓝色背景颜色)
我已经尝试了按照 SO post: 中的建议应用 backgroundImage
的建议,但最终将样式恢复为它在 [= 中的样子42=] 12 你也会失去漂亮的动画。
非常感谢任何指导或建议!我还向 Apple 提交了一份错误报告,看看是否有任何结果。
我也遇到了同样的问题,但没有很好的解决方法。所以我做了这个小的解决方法。我不喜欢它,我也不为此感到自豪,但它确实有效。
func fixBackgroundSegmentControl( _ segmentControl: UISegmentedControl){
if #available(iOS 13.0, *) {
//just to be sure it is full loaded
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
for i in 0...(segmentControl.numberOfSegments-1) {
let backgroundSegmentView = segmentControl.subviews[i]
//it is not enogh changing the background color. It has some kind of shadow layer
backgroundSegmentView.isHidden = true
}
}
}
}
SWIFT 3 & 4+
根据这个答案 ,如果您想要没有灰色覆盖的全白背景,只需将 tintColor
和 backgroundColor
替换为 UIColor.white
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
适合我(Swift 5)。
let background = myColors.background
let selectedColor = myColors.foreground
if #available(iOS 13.0, *)
{
segmentedControl.tintColor = background
segmentedControl.backgroundColor = background
segmentedControl.selectedSegmentTintColor = selectedColor
segmentedControl.setTitleTextAttributes([.foregroundColor: selectedColor as Any], for: .normal)
segmentedControl.setTitleTextAttributes([.foregroundColor: background as Any], for: .selected)
}
else
{
segmentedControl.tintColor = background
segmentedControl.backgroundColor = selectedColor
segmentedControl.layer.cornerRadius = 4
}
在 Xamarin.iOS 这对我有用:
class MySegmentedControl : UISegmentedControl
{
int insertedIndex = 0;
public override void InsertSubview(UIView view, nint atIndex)
{
base.InsertSubview(view, atIndex);
if (insertedIndex == 2 || insertedIndex == 3)
view.Hidden = true;
insertedIndex++;
}
}
我找到了最简单的解决方案。
let segmentControl: UISegmentControl = ...
segmentControl.subviews.forEach { subview in
subview.backgroundColor = .white
}
接受的答案可以简化,我们可以通过继承 UISegmentedControl
并覆盖 layoutSubviews
方法来避免使用 DispatchQueue.main.async
调用:
class SegmentedControl: UISegmentedControl {
override func layoutSubviews() {
super.layoutSubviews()
for i in 0...(numberOfSegments - 1) {
subviews[i].isHidden = true
}
}
}
iOS 13 对 UISegmentedControl 进行了一些更改,包括切换选定段时非常漂亮的动画。但是我注意到它没有正确显示 backgroundColor
属性,它似乎总是带有一点色彩。
我已经看到回答如何设置 selectedSegmentTintColor
之类的问题,但我正在努力将 backgroundColor
设置为 .white
,无论我做什么即使没有应用 tintColor
或类似设置,也总是显示出一点灰色。将 backgroundColor
设置为其他颜色会显示相同的行为,但最明显的是白色。更神秘的是,虽然这种差异出现在 iOS 13 模拟器和物理设备 运行 iOS 13 上,但可视化调试器(在 XCode 11 GM2 中)确实不显示这种差异!
这里有几个屏幕截图显示,即使 UISegmentedControl
的 backgroundColor
设置为与其后面显示的视图的 backgroundColor
相同,它们也略有不同。
设备运行iOS13(白色背景色)
与 Visual Debugger 中显示的相同 view/code(白色背景颜色)
设备运行iOS13(蓝色背景颜色)
我已经尝试了按照 SO post: backgroundImage
的建议,但最终将样式恢复为它在 [= 中的样子42=] 12 你也会失去漂亮的动画。
非常感谢任何指导或建议!我还向 Apple 提交了一份错误报告,看看是否有任何结果。
我也遇到了同样的问题,但没有很好的解决方法。所以我做了这个小的解决方法。我不喜欢它,我也不为此感到自豪,但它确实有效。
func fixBackgroundSegmentControl( _ segmentControl: UISegmentedControl){
if #available(iOS 13.0, *) {
//just to be sure it is full loaded
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
for i in 0...(segmentControl.numberOfSegments-1) {
let backgroundSegmentView = segmentControl.subviews[i]
//it is not enogh changing the background color. It has some kind of shadow layer
backgroundSegmentView.isHidden = true
}
}
}
}
SWIFT 3 & 4+
根据这个答案 tintColor
和 backgroundColor
替换为 UIColor.white
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
适合我(Swift 5)。
let background = myColors.background
let selectedColor = myColors.foreground
if #available(iOS 13.0, *)
{
segmentedControl.tintColor = background
segmentedControl.backgroundColor = background
segmentedControl.selectedSegmentTintColor = selectedColor
segmentedControl.setTitleTextAttributes([.foregroundColor: selectedColor as Any], for: .normal)
segmentedControl.setTitleTextAttributes([.foregroundColor: background as Any], for: .selected)
}
else
{
segmentedControl.tintColor = background
segmentedControl.backgroundColor = selectedColor
segmentedControl.layer.cornerRadius = 4
}
在 Xamarin.iOS 这对我有用:
class MySegmentedControl : UISegmentedControl
{
int insertedIndex = 0;
public override void InsertSubview(UIView view, nint atIndex)
{
base.InsertSubview(view, atIndex);
if (insertedIndex == 2 || insertedIndex == 3)
view.Hidden = true;
insertedIndex++;
}
}
我找到了最简单的解决方案。
let segmentControl: UISegmentControl = ...
segmentControl.subviews.forEach { subview in
subview.backgroundColor = .white
}
接受的答案可以简化,我们可以通过继承 UISegmentedControl
并覆盖 layoutSubviews
方法来避免使用 DispatchQueue.main.async
调用:
class SegmentedControl: UISegmentedControl {
override func layoutSubviews() {
super.layoutSubviews()
for i in 0...(numberOfSegments - 1) {
subviews[i].isHidden = true
}
}
}