Skip to content

Instantly share code, notes, and snippets.

@glennposadas
Created June 23, 2022 09:08
Show Gist options
  • Save glennposadas/18dae4a14a48da1fba567020aa82e8c1 to your computer and use it in GitHub Desktop.
Save glennposadas/18dae4a14a48da1fba567020aa82e8c1 to your computer and use it in GitHub Desktop.
Vertical button with underline view
//
// ViewController.swift
// Button
//
// Created by Glenn Posadas on 6/23/22.
//
import UIKit
class ViewController: UIViewController {
var button: VerticalButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .red
button = VerticalButton(icon: .init(named: "ic_poll_results")!, title: "Results")
button.addTarget(self, action: #selector(boom), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.widthAnchor.constraint(equalToConstant: 50),
button.heightAnchor.constraint(equalToConstant: 50),
])
}
@objc
func boom() {
button.isSelected.toggle()
}
}
/**
A custom `UIButton` that has custom label and imageView
which are both aligned vertically. Image at the top, label at the bottom.
*/
class VerticalButton: UIButton {
private(set) var icon: UIImage!
private(set) var title: String!
private(set) var underlineView: UIView!
private var contentView: UIView!
convenience init(icon: UIImage, title: String) {
self.init(frame: .zero)
self.icon = icon
self.title = title
layout()
}
override var isSelected: Bool {
didSet {
UIView.animate(withDuration: 0.1) {
self.underlineView.alpha = self.isSelected ? 1 : 0
}
}
}
override var isHighlighted: Bool {
didSet {
self.contentView.alpha = self.isHighlighted ? 0.6 : 1.0
}
}
}
private extension VerticalButton {
func layout() {
let imageView = UIImageView(image: icon)
imageView.isUserInteractionEnabled = false
imageView.contentMode = .scaleAspectFit
let titleLabel = UILabel()
titleLabel.font = .systemFont(ofSize: 14)
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.isUserInteractionEnabled = false
titleLabel.textColor = .white
let stackView = UIStackView(arrangedSubviews: [
imageView,
titleLabel
])
stackView.axis = .vertical
stackView.spacing = 4
stackView.isUserInteractionEnabled = false
stackView.translatesAutoresizingMaskIntoConstraints = false
underlineView = UIView()
underlineView.alpha = isSelected ? 1 : 0
underlineView.backgroundColor = .white
underlineView.isUserInteractionEnabled = false
underlineView.translatesAutoresizingMaskIntoConstraints = false
contentView = UIView()
contentView.isUserInteractionEnabled = false
contentView.translatesAutoresizingMaskIntoConstraints = false
addSubview(contentView)
contentView.addSubview(stackView)
contentView.addSubview(underlineView)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: topAnchor),
contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: trailingAnchor),
stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
underlineView.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
underlineView.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
underlineView.heightAnchor.constraint(equalToConstant: 1),
underlineView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor)
])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment