Files
Attractor/App/Common UI/SegmentedReliefButton.swift

112 lines
3.9 KiB
Swift
Raw Permalink Normal View History

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 }
}
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
backgroundsContainerView.clipsToBounds = true
2021-06-14 16:32:51 -07:00
backgroundsContainerView.layer.cornerRadius = self.cornerRadius + Self.borderWidth + 1.0
backgroundsContainerView.layer.cornerCurve = .continuous
constrainedToSquare = false
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 {
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)
}
override func setBackgroundInverted(_ inverted: Bool) {
// no-op
2020-08-14 15:55:08 -07:00
}
override func layoutSubviews() {
super.layoutSubviews()
backgroundView.colors = [ .clear ]
2020-08-14 15:55:08 -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)
)
let darkMode = self.traitCollection.userInterfaceStyle == .dark
2021-06-14 16:32:51 -07:00
var buttonXOffset = CGFloat(Self.borderWidth)
for (i, child) in children.enumerated() {
2020-08-14 15:55:08 -07:00
child.shadowView.isHidden = true
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
// 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,
height: bounds.height
))
separatorView.backgroundColor = .systemFill
backgroundsContainerView.addSubview(separatorView)
}
2020-08-14 15:55:08 -07:00
}
}
}