将 UISegmentedControl 的颜色与半透明导航栏的颜色相匹配

Match UISegmentedControl's color with that of translucent navigation bar

我正在(半透明)导航栏正下方添加一个分段控件,并希望它具有相同的颜色。我试图让它看起来像是导航栏的一部分。

isOpaque = false
layer.opacity = 0.85
let bkImg = UIImage(color: .systemBackground.withAplhaComponent(0.85), size: CGSize(width: 1, height: 16))
segmentedCtrl.setBackgroundImage(bkImg, for: .normal, barMetrics: .default)
setDividerImage(bkImg, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)

我试过调整分段控件的不透明度和 bkImg 的颜色,但这根本没有效果。从头开始编写自定义标签栏会更快 - iOS 13 中的分段控件无法自定义。

这完全是破解,但看起来不错。

class CustomSegmentedControl: UISegmentedControl {
    private var underline: UIView!

    init() {
        super.init(frame: .zero)

        underline = UIView()
        underline.backgroundColor = tintColor
        view.addSubvie(underline)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        // Set background color to match navigation bar
        let bgColor = UIColor.systemBackground.hsbComponents.brightness == 1.0
            ? UIColor.black.withAlphaComponent(0.028) // light
            : UIColor.white.withAlphaComponent(0.073) // dark
        let img = UIImage(color: bgColor, size: CGSize(width: 1, height: 16))
        setBackgroundImage(img, for: .normal, barMetrics: .default)
        setDividerImage(img, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)

        // Bonus: underline below selected tab
        var frame = underline.frame
        let tabWidth = self.frame.width / CGFloat(numberOfSegments)
        frame.origin.x = CGFloat(selectedSegmentIndex) * tabWidth
        frame.origin.y = self.frame.height - 2.0
        frame.size.width = tabWidth
        underline.frame = frame
    }
}

可以通过将 UISegmentedControl 放在 UIToolbar 内,并将 UIToolbar 放在 UINavigationBar 下方来实现此效果。一旦进入 UIToolbarUISegmentedControl 就会呈现出与 UINavigationBar.

相同的外观

如果您希望 UIToolBar 融入 UINavigationBar,您需要对 UIToolBar 应用所有与 [=13] 相同的外观选项=](例如 barTintColortintColor)。

我不知道如何调整 UISegmentedControl 本身以模仿导航栏和工具栏应用的外观,但使用此策略我们不需要。