Nicer toolbar buttons

This commit is contained in:
James Magahern
2020-08-14 15:55:08 -07:00
parent 9b36a3ace5
commit 69029a3195
12 changed files with 534 additions and 187 deletions

View File

@@ -7,154 +7,20 @@
import UIKit
class ToolbarButtonView: UIView
{
private var buttonPadding = CGFloat(24.0)
private var buttonViews: [UIView] = []
public var numberOfButtonViews: Int { buttonViews.count }
func addButtonView(_ button: UIView) {
buttonViews.append(button)
addSubview(button)
setNeedsLayout()
}
func removeAllButtonViews() {
buttonViews.forEach { $0.removeFromSuperview() }
buttonViews.removeAll()
setNeedsLayout()
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
let width: CGFloat = buttonViews.reduce(buttonPadding / 2.0) { (result, button) -> CGFloat in
return result + button.sizeThatFits(size).width + buttonPadding
}
return CGSize(width: width, height: size.height)
}
override func layoutSubviews() {
var buttonRect = CGRect(origin: .zero, size: CGSize(width: 0, height: bounds.height))
for button in buttonViews {
let buttonSize = button.sizeThatFits(bounds.size)
buttonRect.size = CGSize(width: buttonSize.width + buttonPadding, height: bounds.height)
button.frame = buttonRect
buttonRect.origin.x += buttonRect.width
}
}
}
class ToolbarView: UIView
{
var urlBar: URLBar? { didSet { containerView.addSubview(urlBar!) } }
var cancelButtonVisible: Bool = false { didSet { layoutSubviews() } }
let containerView = UIView(frame: .zero)
let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
let cancelButton = UIButton(type: .system)
let leadingButtonsView = ToolbarButtonView(frame: .zero)
let trailingButtonsView = ToolbarButtonView(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)
// Cancel button
let urlBarPadding: CGFloat = 8.0
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)
} 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) + urlBarPadding, y: 0), size: trailingContainerSize)
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 {
let origin = CGPoint(
x: leadingButtonsView.frame.maxX,
y: 0.0
)
urlBar.frame = CGRect(
origin: origin,
size: CGSize(
width: containerView.bounds.width - avoidingSize.width - origin.x,
height: containerView.bounds.height
)
)
}
}
}
class ToolbarViewController: UIViewController
{
let urlBar = URLBar()
let toolbarView = ToolbarView()
let scriptControllerIconView = ScriptControllerIconView()
let shareButton = UIButton(frame: .zero)
let darkModeButton = UIButton(frame: .zero)
let windowButton = UIButton(frame: .zero)
let backButton = UIButton(frame: .zero)
let forwardButton = UIButton(frame: .zero)
let newTabButton = UIButton(frame: .zero)
let shareButton = ReliefButton()
let darkModeButton = ReliefButton()
let windowButton = ReliefButton()
let newTabButton = ReliefButton()
let backButton = ReliefButton()
let forwardButton = ReliefButton()
let navigationSegmentedButton = SegmentedReliefButton(children: [])
var darkModeEnabled: Bool = false {
didSet {
@@ -189,6 +55,9 @@ class ToolbarViewController: UIViewController
// Forward button
forwardButton.setImage(UIImage(systemName: "chevron.right"), for: .normal)
// Navigation control
navigationSegmentedButton.children = [ backButton, forwardButton ]
// New tab button
newTabButton.setImage(UIImage(systemName: "plus"), for: .normal)
@@ -214,18 +83,27 @@ class ToolbarViewController: UIViewController
toolbarView.leadingButtonsView.removeAllButtonViews()
toolbarView.trailingButtonsView.removeAllButtonViews()
let spacerView = { () -> SpacerView in
SpacerView(space: 24.0)
}
// Setup toolbar based on trait collection
if traitCollection.horizontalSizeClass == .compact {
toolbarView.trailingButtonsView.addButtonView(darkModeButton)
toolbarView.trailingButtonsView.addButtonView(scriptControllerIconView)
toolbarView.trailingButtonsView.addButtonView(windowButton)
} else {
toolbarView.leadingButtonsView.addButtonView(backButton)
toolbarView.leadingButtonsView.addButtonView(forwardButton)
toolbarView.leadingButtonsView.addButtonView(navigationSegmentedButton)
toolbarView.leadingButtonsView.addButtonView(spacerView())
toolbarView.trailingButtonsView.addButtonView(shareButton)
toolbarView.trailingButtonsView.addButtonView(spacerView())
toolbarView.trailingButtonsView.addButtonView(darkModeButton)
toolbarView.trailingButtonsView.addButtonView(shareButton)
toolbarView.trailingButtonsView.addButtonView(scriptControllerIconView)
toolbarView.trailingButtonsView.addButtonView(spacerView())
toolbarView.trailingButtonsView.addButtonView(newTabButton)
toolbarView.trailingButtonsView.addButtonView(windowButton)
}
@@ -239,3 +117,16 @@ class ToolbarViewController: UIViewController
fatalError("init(coder:) has not been implemented")
}
}
class SpacerView: UIView {
internal var space: CGFloat = 0
convenience init(space: CGFloat) {
self.init(frame: .zero)
self.space = space
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
CGSize(width: space, height: size.height)
}
}