// // 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() } } private let backgroundsContainerView = UIView(frame: .zero) private var childrenHighlighObservations: [NSKeyValueObservation] = [] init(children: [ReliefButton]) { super.init() self.children = children backgroundsContainerView.clipsToBounds = true backgroundsContainerView.layer.cornerRadius = Self.cornerRadius - Self.borderWidth constrainedToSquare = false addSubview(backgroundsContainerView) } override var isHighlighted: Bool { didSet {} } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } 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: ourSize.height) } override func setBackgroundInverted(_ inverted: Bool) { // no-op } override func layoutSubviews() { super.layoutSubviews() backgroundView.colors = [ .clear ] 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 (i, child) in children.enumerated() { child.shadowView.isHidden = true child.backgroundView.isHidden = true bringSubviewToFront(child) let childSize = child.sizeThatFits(bounds.size) buttonRect.size = CGSize(width: childSize.width, height: bounds.height) 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) } } } }