Skip to content

Instantly share code, notes, and snippets.

@fmo91
Created October 4, 2016 17:08
Show Gist options
  • Save fmo91/03e2edcf43edb15212835671b5ddd6a2 to your computer and use it in GitHub Desktop.
Save fmo91/03e2edcf43edb15212835671b5ddd6a2 to your computer and use it in GitHub Desktop.
Simple UIButton subclass that can show a customizable loading message
//
// LoadingButton.swift
// LoadingButton
//
// Created by Fernando Ortiz on 4/10/16.
// Copyright © 2016 Fernando Martín Ortiz. All rights reserved.
//
import UIKit
/**
Simple UIButton subclass that can show a customizable loading message
There are two important methods here:
- startLoading(): Starts the loading animation and shows the loading message
- stopLoading(): Stops the loading animation and shows the normal title.
And has some customizable properties that can be inspected from Interface builder:
- loadingText: The custom message that is shown when the loading animation starts. Defaults to "Loading..."
- loadingLabelFontName: The custom font name for the loading label. The default font is System font with size 15.0
- loadingLabelFontSize: The custom font size for the loading label. The default font is System font with size 15.0
- loadingLabelColor: The custom textColor for the loading label. Defaults to blue.
*/
class LoadingButton: UIButton {
// MARK: - Views -
lazy var activityIndicatorView: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()
return activityIndicator
}()
lazy var loadingLabel: UILabel = {
let label = UILabel()
return label
}()
lazy var loadingStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.spacing = 5.0
return stackView
}()
// MARK: - Attributes -
/// The custom message that is shown when the loading animation starts. Defaults to "Loading..."
@IBInspectable
var loadingText: String = "Loading..." {
didSet {
configureIBProperties()
}
}
/// The custom font name for the loading label. The default font is System font with size 15.0
@IBInspectable
var loadingLabelFontName: String? = nil {
didSet {
configureIBProperties()
}
}
/// The custom font size for the loading label. The default font is System font with size 15.0
@IBInspectable
var loadingLabelFontSize: CGFloat = 15.0 {
didSet {
configureIBProperties()
}
}
/// The custom textColor for the loading label. Defaults to blue.
@IBInspectable
var loadingLabelColor: UIColor = UIColor.blue {
didSet {
configureIBProperties()
}
}
private var lastTitle: String? = nil
private lazy var defaultFont: UIFont = {
let font = UIFont.systemFont(ofSize: 15.0)
return font
}()
// MARK: - Init -
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
loadingStackView.addArrangedSubview(activityIndicatorView)
loadingStackView.addArrangedSubview(loadingLabel)
addSubview(loadingStackView)
loadingStackView.translatesAutoresizingMaskIntoConstraints = false
loadingStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
loadingStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
loadingStackView.isHidden = true
configureIBProperties()
}
// MARK: - Private configuration -
private func configureIBProperties() {
self.loadingLabel.text = loadingText
self.loadingLabel.textColor = loadingLabelColor
if let fontName = self.loadingLabelFontName {
self.loadingLabel.font = UIFont(name: fontName, size: self.loadingLabelFontSize)
} else {
self.loadingLabel.font = self.defaultFont
}
}
// MARK: - Public methods -
/// Starts the loading animation and shows the loading message
func startLoading() {
if lastTitle == nil {
self.lastTitle = self.titleLabel?.text
}
self.setTitle("", for: .normal)
self.loadingStackView.isHidden = false
self.activityIndicatorView.startAnimating()
}
/// Stops the loading animation and shows the normal title.
func stopLoading() {
self.setTitle(self.lastTitle, for: .normal)
self.lastTitle = nil
self.loadingStackView.isHidden = true
self.activityIndicatorView.stopAnimating()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment