// // ToolbarView.swift // App // // Created by James Magahern on 8/14/20. // import UIKit class ToolbarView: UIView { var urlBar: URLBar? { didSet { containerView.addSubview(urlBar!) } } var cancelButtonVisible: Bool = false { didSet { layoutSubviews() } } let containerView = UIView(frame: .zero) let backgroundView = GradientView(direction: .vertical, colors: [.tertiarySystemGroupedBackground, .secondarySystemGroupedBackground]) let cancelButton = UIButton(type: .system) let leadingButtonsView = ToolbarButtonContainerView(frame: .zero) let trailingButtonsView = ToolbarButtonContainerView(frame: .zero) convenience init() { self.init(frame: .zero) addSubview(backgroundView) addSubview(containerView) containerView.addSubview(leadingButtonsView) containerView.addSubview(trailingButtonsView) cancelButton.setTitle("Cancel", for: .normal) containerView.addSubview(cancelButton) layer.masksToBounds = false layer.shadowColor = UIColor.black.cgColor layer.shadowOpacity = 0.2 layer.shadowOffset = CGSize(width: 0.0, height: 1.0) layer.shadowRadius = 1.5 } override func sizeThatFits(_ size: CGSize) -> CGSize { return CGSize(width: size.width, height: 44.0) } override func layoutSubviews() { super.layoutSubviews() backgroundView.frame = bounds var containerBounds = bounds containerBounds.size.height -= safeAreaInsets.bottom containerView.frame = containerBounds containerView.frame = containerView.frame.insetBy(dx: 8.0, dy: 4.0) let buttonContainerInset = UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0) let urlBarPadding = CGFloat(8.0) var urlBarInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0) // Cancel button var cancelButtonSize = cancelButton.sizeThatFits(containerView.bounds.size) cancelButtonSize.width += (urlBarPadding * 2) cancelButton.frame = CGRect(origin: CGPoint(x: (containerView.bounds.maxX - cancelButtonSize.width), y: 0), size: CGSize(width: cancelButtonSize.width + urlBarPadding, height: containerView.bounds.height)) // Leading toolbar buttons if leadingButtonsView.numberOfButtonViews > 0 { let leadingContainerSize = leadingButtonsView.sizeThatFits(containerView.bounds.size) leadingButtonsView.frame = CGRect(origin: .zero, size: leadingContainerSize).inset(by: buttonContainerInset) urlBarInsets.left = urlBarPadding } else { leadingButtonsView.frame = .zero } // Trailing toolbar buttons let trailingContainerSize = trailingButtonsView.sizeThatFits(containerView.bounds.size) trailingButtonsView.frame = CGRect(origin: CGPoint(x: (containerView.bounds.maxX - trailingContainerSize.width), y: 0), size: trailingContainerSize) trailingButtonsView.frame = trailingButtonsView.frame.inset(by: buttonContainerInset) urlBarInsets.right = urlBarPadding var avoidingSize: CGSize = .zero if cancelButtonVisible { cancelButton.alpha = 1.0 trailingButtonsView.alpha = 0.0 avoidingSize = cancelButtonSize } else { cancelButton.alpha = 0.0 trailingButtonsView.alpha = 1.0 avoidingSize = trailingContainerSize } if let urlBar = urlBar { var origin = CGPoint( x: leadingButtonsView.frame.maxX, y: 0.0 ) if origin.x == 0 { // Add some padding if url bar is flush with side origin.x = layoutMargins.left } urlBar.frame = CGRect( origin: origin, size: CGSize( width: containerView.bounds.width - avoidingSize.width - origin.x, height: trailingContainerSize.height ) ) urlBar.frame = urlBar.frame.inset(by: urlBarInsets).inset(by: buttonContainerInset) } } }