Skip to content

Instantly share code, notes, and snippets.

@apatronl
Last active June 14, 2020 05:45
Show Gist options
  • Save apatronl/9b9099fdd0cea1e8f51f15c90dd3544e to your computer and use it in GitHub Desktop.
Save apatronl/9b9099fdd0cea1e8f51f15c90dd3544e to your computer and use it in GitHub Desktop.
Button Panel View Demo
import UIKit
fileprivate let buttonSize: CGFloat = 56
fileprivate let shadowOpacity: Float = 0.7
class ButtonPanelView: UIView {
lazy var menuButton: UIButton = {
let button = UIButton(frame: .zero)
button.setTitle("➕", for: .normal)
button.backgroundColor = .clear
button.layer.cornerRadius = buttonSize / 2
button.addTarget(
self, action: #selector(handleTogglePanelButtonTapped(_:)), for: .touchUpInside)
return button
}()
lazy var dogButton: UIButton = {
let button = UIButton(frame: .zero)
button.setTitle("🐶", for: .normal)
button.layer.cornerRadius = buttonSize / 2
button.isHidden = true
return button
}()
lazy var catButton: UIButton = {
let button = UIButton(frame: .zero)
button.setTitle("🐱", for: .normal)
button.layer.cornerRadius = buttonSize / 2
button.isHidden = true
return button
}()
lazy var expandedStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.isHidden = true
stackView.addArrangedSubview(dogButton)
stackView.addArrangedSubview(catButton)
return stackView
}()
lazy var containerStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.addArrangedSubview(expandedStackView)
stackView.addArrangedSubview(menuButton)
return stackView
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(red: 81/255, green: 166/255, blue: 219/255, alpha: 1)
layer.cornerRadius = buttonSize / 2
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOpacity = shadowOpacity
layer.shadowOffset = .zero
addSubview(containerStackView)
setConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setConstraints() {
// Main button
menuButton.translatesAutoresizingMaskIntoConstraints = false
menuButton.widthAnchor.constraint(equalToConstant: buttonSize).isActive = true
menuButton.heightAnchor.constraint(equalToConstant: buttonSize).isActive = true
// Dog button
dogButton.translatesAutoresizingMaskIntoConstraints = false
dogButton.widthAnchor.constraint(equalToConstant: buttonSize).isActive = true
dogButton.heightAnchor.constraint(equalToConstant: buttonSize).isActive = true
// Cat button
catButton.translatesAutoresizingMaskIntoConstraints = false
catButton.widthAnchor.constraint(equalToConstant: buttonSize).isActive = true
catButton.heightAnchor.constraint(equalToConstant: buttonSize).isActive = true
// Container stack view
containerStackView.translatesAutoresizingMaskIntoConstraints = false
containerStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
containerStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
translatesAutoresizingMaskIntoConstraints = false
self.widthAnchor.constraint(equalTo: containerStackView.widthAnchor).isActive = true
self.heightAnchor.constraint(equalTo: containerStackView.heightAnchor).isActive = true
}
}
// MARK: - Gestures
extension ButtonPanelView {
@objc private func handleTogglePanelButtonTapped(_ sender: UIButton) {
let willExpand = expandedStackView.isHidden
let menuButtonNewTitle = willExpand ? "❌" : "➕"
UIView.animate(
withDuration: 0.3, delay: 0, options: .curveEaseIn,
animations: {
self.expandedStackView.subviews.forEach { $0.isHidden = !$0.isHidden }
self.expandedStackView.isHidden = !self.expandedStackView.isHidden
if willExpand {
self.menuButton.setTitle(menuButtonNewTitle, for: .normal)
}
}, completion: { _ in
// When collapsing, wait for animation to finish before changing from "x" to "+"
if !willExpand {
self.menuButton.setTitle(menuButtonNewTitle, for: .normal)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment