Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kelvinfok/a894d87ad9974d2067ad400555be0d48 to your computer and use it in GitHub Desktop.
Save kelvinfok/a894d87ad9974d2067ad400555be0d48 to your computer and use it in GitHub Desktop.
Pinterest Floating Bar
//
// FloatingBarView.swift
// ios-flickr-browser
//
// Created by Kelvin Fok on 17/5/21.
// Referenced from https://github.com/chrishoste/printerest-tabbar/tree/master/PrinterestTabBar/Controller
//
import UIKit
protocol FloatingBarViewDelegate: AnyObject {
func floatingBarViewDidSelect(indexAt index: Int)
}
class FloatingBarView: UIView {
weak var delegate: FloatingBarViewDelegate?
var buttons: [UIButton] = []
init(items: [String]) {
super.init(frame: .zero)
backgroundColor = .white
setupStackView(items)
updateUI(selectedIndex: 0)
}
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = bounds.height / 2
layer.shadowPath = UIBezierPath(rect: bounds).cgPath
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.1
layer.shadowOffset = .zero
layer.shadowRadius = bounds.height / 2
}
func setupStackView(_ items: [String]) {
for (index, item) in items.enumerated() {
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 20, weight: .bold, scale: .medium)
let normalImage = UIImage(systemName: item, withConfiguration: symbolConfig)
let selectedImage = UIImage(systemName: "\(item).fill", withConfiguration: symbolConfig)
let button = createButton(normalImage: normalImage!, selectedImage: selectedImage!, index: index)
buttons.append(button)
}
let stackView = UIStackView(arrangedSubviews: buttons)
addSubview(stackView)
stackView.snp.makeConstraints { (make) in
make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16))
}
}
func createButton(normalImage: UIImage, selectedImage: UIImage, index: Int) -> UIButton {
let button = UIButton()
button.snp.makeConstraints { (make) in
make.width.height.equalTo(60)
}
button.setImage(normalImage, for: .normal)
button.setImage(selectedImage, for: .selected)
button.tag = index
button.adjustsImageWhenHighlighted = false
button.addTarget(self, action: #selector(changeTab(_:)), for: .touchUpInside)
return button
}
@objc func changeTab(_ sender: UIButton) {
sender.pulse()
delegate?.floatingBarViewDidSelect(indexAt: sender.tag)
updateUI(selectedIndex: sender.tag)
}
func updateUI(selectedIndex: Int) {
for (index, button) in buttons.enumerated() {
if index == selectedIndex {
button.isSelected = true
button.tintColor = .black
} else {
button.isSelected = false
button.tintColor = .gray
}
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func toggle(shouldShow: Bool) {
if shouldShow {
isHidden = !shouldShow
}
UIView.animate(withDuration: 0.25, delay: 0, usingSpringWithDamping: 1,
initialSpringVelocity: 0.5, options: .curveEaseOut, animations: {
self.alpha = shouldShow ? 1 : 0
self.transform = shouldShow ? .identity : CGAffineTransform(translationX: 0, y: 10)
}) { (_) in
if shouldShow {
self.isHidden = !shouldShow
}
}
}
}
extension UIButton {
func pulse() {
let pulse = CASpringAnimation(keyPath: "transform.scale")
pulse.duration = 0.15
pulse.fromValue = 0.95
pulse.toValue = 1.0
layer.add(pulse, forKey: "pulse")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment