swift 如何在iOS 13中将UI分段控件的背景色设置为白色

h7wcgrx3  于 2022-12-22  发布在  Swift
关注(0)|答案(7)|浏览(252)

iOS 13对UISegmentedControl做了一些修改,包括切换所选片段时的动画效果非常好。不过我注意到backgroundColor属性显示不正确,它似乎总是带有一点色彩。
我看到过一些问题,可以回答如何设置selectedSegmentTintColor等问题,但我很难将backgroundColor设置为.white,无论我做什么,它总是显示一点灰色,即使没有tintColor或类似的设置应用。设置backgroundColor到其他颜色显示相同的行为,但它最明显的白色。更令人费解的是,虽然这种差异在iOS 13模拟器和运行iOS 13的物理设备上都显示出来,但可视化调试器(XCode 11 GM 2中)却没有显示这种差异!
这里有几个屏幕截图,显示即使UISegmentedControlbackgroundColor设置为与后面显示的视图的backgroundColor相同,它们也略有不同。
运行iOS 13的设备(白色背景彩色)x1c 0d1x
可视化调试器中显示的视图/代码相同(白色背景色)

运行iOS 13的设备(蓝色背景色)

我已经尝试了应用backgroundImage的建议,如这篇SO帖子中所建议的:UISegmentedControl iOS 13 clear color,但这最终会将风格恢复到iOS 12中的样子,你也会失去漂亮的动画。
任何指导或建议都非常感谢!我也向苹果提交了一份错误报告,看看是否有什么结果。

ldxq2e6h

ldxq2e6h1#

我也有同样的问题,但没有很酷的方法来解决它。所以我做了这个小的变通办法。我不喜欢它,我也不为此感到自豪,但它的工作。

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

k10s72fa2#

我找到了最简单的解决办法。

let segmentControl: UISegmentControl = ... 
segmentControl.subviews.forEach { subview in
  subview.backgroundColor = .white
}
fjaof16o

fjaof16o3#

为我工作(斯威夫特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
}
bmvo0sr5

bmvo0sr54#

SWIFT 3和4+
从这个答案https://stackoverflow.com/a/31652184/3249196,如果你想要一个没有灰色覆盖的全白色背景,只需将tintColorbackgroundColor替换为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!
    }
}
4zcjmb1e

4zcjmb1e5#

可接受的答案可以简化,我们可以通过子类化UISegmentedControl并重写layoutSubviews方法来避免使用DispatchQueue.main.async调用:

class SegmentedControl: UISegmentedControl {
  override func layoutSubviews() {
    super.layoutSubviews()
    for i in 0...(numberOfSegments - 1)  {
      subviews[i].isHidden = true
    }
  }
}
blpfk2vs

blpfk2vs6#

我完成了前一个答案的代码,一切都为我工作

extension UISegmentedControl {

    func applyWhiteBackgroundColor() {
        // for remove bottom shadow of selected element
        self.selectedSegmentTintColor = selectedSegmentTintColor?.withAlphaComponent(0.99)
        if #available(iOS 13.0, *) {
            //just to be sure it is full loaded
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
                guard let self = self else {
                    return
                }
                for i in 0 ..< (self.numberOfSegments)  {
                    let backgroundSegmentView = self.subviews[i]
                    //it is not enogh changing the background color. It has some kind of shadow layer
                    backgroundSegmentView.isHidden = true
                }
            }
        }
    }
}

}
Modified Segmented Control

dfuffjeb

dfuffjeb7#

在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++;
    }
}

相关问题