2020-08-14 15:55:08 -07:00
|
|
|
//
|
|
|
|
|
// SegmentedReliefButton.swift
|
|
|
|
|
// App
|
|
|
|
|
//
|
|
|
|
|
// Created by James Magahern on 8/14/20.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
|
|
|
|
|
|
class SegmentedReliefButton: ReliefButton
|
|
|
|
|
{
|
|
|
|
|
var children: [ReliefButton] = [] {
|
|
|
|
|
willSet { children.forEach { $0.removeFromSuperview() } }
|
|
|
|
|
didSet { children.forEach { addSubview($0) }; setNeedsLayout() }
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-19 17:55:24 -07:00
|
|
|
override var isPointerInteractionEnabled: Bool {
|
|
|
|
|
set { children.forEach { $0.isPointerInteractionEnabled = newValue } }
|
|
|
|
|
get { children.first?.isPointerInteractionEnabled ?? false }
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-14 18:42:40 -07:00
|
|
|
private let backgroundsContainerView = UIView(frame: .zero)
|
|
|
|
|
private var childrenHighlighObservations: [NSKeyValueObservation] = []
|
|
|
|
|
|
2020-08-14 15:55:08 -07:00
|
|
|
init(children: [ReliefButton]) {
|
|
|
|
|
super.init()
|
|
|
|
|
self.children = children
|
2020-08-14 18:42:40 -07:00
|
|
|
|
|
|
|
|
backgroundsContainerView.clipsToBounds = true
|
2021-06-14 16:32:51 -07:00
|
|
|
backgroundsContainerView.layer.cornerRadius = self.cornerRadius + Self.borderWidth + 1.0
|
|
|
|
|
backgroundsContainerView.layer.cornerCurve = .continuous
|
2020-09-30 18:26:45 -07:00
|
|
|
|
|
|
|
|
constrainedToSquare = false
|
2020-08-14 18:42:40 -07:00
|
|
|
|
|
|
|
|
addSubview(backgroundsContainerView)
|
2020-08-14 15:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override var isHighlighted: Bool {
|
2021-04-19 17:55:24 -07:00
|
|
|
// Does not highlight. Only children do.
|
|
|
|
|
set {} get { false }
|
2020-08-14 15:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
required init?(coder: NSCoder) {
|
|
|
|
|
fatalError("init(coder:) has not been implemented")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
2020-08-14 18:42:40 -07:00
|
|
|
let ourSize = super.sizeThatFits(size)
|
2020-08-14 15:55:08 -07:00
|
|
|
let width: CGFloat = children.reduce(0.0) { (result, button) -> CGFloat in
|
|
|
|
|
return result + button.sizeThatFits(size).width
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-14 16:32:51 -07:00
|
|
|
return CGSize(width: width + (2 * Self.borderWidth), height: ourSize.height)
|
2020-08-14 18:42:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func setBackgroundInverted(_ inverted: Bool) {
|
|
|
|
|
// no-op
|
2020-08-14 15:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func layoutSubviews() {
|
|
|
|
|
super.layoutSubviews()
|
|
|
|
|
|
2020-08-14 18:42:40 -07:00
|
|
|
backgroundView.colors = [ .clear ]
|
2020-08-14 15:55:08 -07:00
|
|
|
|
2020-08-14 18:42:40 -07:00
|
|
|
backgroundsContainerView.frame = backgroundView.frame
|
|
|
|
|
|
|
|
|
|
childrenHighlighObservations.removeAll()
|
|
|
|
|
backgroundsContainerView.subviews.forEach { $0.removeFromSuperview() }
|
|
|
|
|
|
2021-06-14 16:32:51 -07:00
|
|
|
let paddedSize = CGSize(
|
|
|
|
|
width: bounds.size.width - (Self.borderWidth * 2.0),
|
|
|
|
|
height: bounds.size.height - (Self.borderWidth * 2.0)
|
|
|
|
|
)
|
|
|
|
|
|
2020-08-14 18:42:40 -07:00
|
|
|
let darkMode = self.traitCollection.userInterfaceStyle == .dark
|
2021-06-14 16:32:51 -07:00
|
|
|
var buttonXOffset = CGFloat(Self.borderWidth)
|
2020-08-14 18:42:40 -07:00
|
|
|
for (i, child) in children.enumerated() {
|
2020-08-14 15:55:08 -07:00
|
|
|
child.shadowView.isHidden = true
|
2020-08-14 18:42:40 -07:00
|
|
|
child.backgroundView.isHidden = true
|
2020-08-14 15:55:08 -07:00
|
|
|
bringSubviewToFront(child)
|
|
|
|
|
|
2021-06-14 16:32:51 -07:00
|
|
|
let childSize = child.sizeThatFits(paddedSize)
|
|
|
|
|
child.frame = CGRect(
|
|
|
|
|
origin: CGPoint(x: buttonXOffset, y: Self.borderWidth),
|
|
|
|
|
size: CGSize(width: childSize.width, height: paddedSize.height)
|
|
|
|
|
)
|
2020-08-14 15:55:08 -07:00
|
|
|
|
2021-06-14 16:32:51 -07:00
|
|
|
buttonXOffset += child.frame.width
|
2020-08-14 18:42:40 -07:00
|
|
|
|
|
|
|
|
// 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,
|
2021-06-14 16:32:51 -07:00
|
|
|
width: 1.0 / UIScreen.main.scale,
|
2020-08-14 18:42:40 -07:00
|
|
|
height: bounds.height
|
|
|
|
|
))
|
|
|
|
|
separatorView.backgroundColor = .systemFill
|
|
|
|
|
backgroundsContainerView.addSubview(separatorView)
|
|
|
|
|
}
|
2020-08-14 15:55:08 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|