I am adding a segmented control directly under the (translucent) navigation bar, and want it to have the same color. I am trying to make it look like it's part of the 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)
I've tried playing with the opacity of the segmented control, and the color of bkImg
, but that has no effect at all. It would have been quicker to just write a custom tab bar from scratch - the segmented control in iOS 13 is impossible to customize.
This is a total hack, but it looks good.
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
}
}