SegmentedReliefButton: actually show background states

This commit is contained in:
James Magahern
2020-08-14 18:42:40 -07:00
parent fa4ba64660
commit f2190abb6e
3 changed files with 78 additions and 13 deletions

View File

@@ -14,9 +14,22 @@ class SegmentedReliefButton: ReliefButton
didSet { children.forEach { addSubview($0) }; setNeedsLayout() }
}
private let backgroundMaskView = UIView(frame: .zero)
private let backgroundsContainerView = UIView(frame: .zero)
private var childrenHighlighObservations: [NSKeyValueObservation] = []
init(children: [ReliefButton]) {
super.init()
self.children = children
backgroundMaskView.backgroundColor = .black
backgroundMaskView.layer.masksToBounds = true
backgroundMaskView.layer.cornerRadius = Self.cornerRadius - Self.borderWidth
backgroundsContainerView.clipsToBounds = true
backgroundsContainerView.mask = backgroundMaskView
addSubview(backgroundsContainerView)
}
override var isHighlighted: Bool {
@@ -28,23 +41,36 @@ class SegmentedReliefButton: ReliefButton
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
let ourSize = super.sizeThatFits(size)
let width: CGFloat = children.reduce(0.0) { (result, button) -> CGFloat in
return result + button.sizeThatFits(size).width
}
return CGSize(width: width, height: size.height)
return CGSize(width: width, height: ourSize.height)
}
override func setBackgroundInverted(_ inverted: Bool) {
// no-op
}
override func layoutSubviews() {
super.layoutSubviews()
backgroundView.colors = [ .clear ]
backgroundView.frame = bounds
shadowView.frame = bounds
backgroundMaskView.frame = backgroundView.frame.insetBy(dx: 1.0, dy: 1.0)
backgroundsContainerView.frame = backgroundView.frame
childrenHighlighObservations.removeAll()
backgroundsContainerView.subviews.forEach { $0.removeFromSuperview() }
let darkMode = self.traitCollection.userInterfaceStyle == .dark
var buttonRect = CGRect(origin: .zero, size: CGSize(width: 0, height: bounds.height))
for child in children {
for (i, child) in children.enumerated() {
child.shadowView.isHidden = true
child.backgroundView.layer.borderWidth = 0
child.backgroundView.isHidden = true
bringSubviewToFront(child)
let childSize = child.sizeThatFits(bounds.size)
@@ -52,6 +78,26 @@ class SegmentedReliefButton: ReliefButton
child.frame = buttonRect
buttonRect.origin.x += buttonRect.width
// Background
let backgroundView = GradientView(direction: .vertical, colors: Self.gradientColors(inverted: false, darkMode: darkMode))
backgroundView.frame = child.frame
backgroundsContainerView.insertSubview(backgroundView, at: 0)
childrenHighlighObservations.append(child.observe(\.isHighlighted) { [backgroundView] (button, changeEvent) in
backgroundView.colors = Self.gradientColors(inverted: button.isHighlighted, darkMode: darkMode)
})
// Separator
if i < children.count - 1 {
let separatorView = UIView(frame: CGRect(
x: child.frame.maxX,
y: 0,
width: 1.0,
height: bounds.height
))
separatorView.backgroundColor = .systemFill
backgroundsContainerView.addSubview(separatorView)
}
}
}
}