Skip to content

Instantly share code, notes, and snippets.

@fruitcoder
Created December 2, 2016 11:09
Show Gist options
  • Save fruitcoder/e3895060644d35b1b7c55bb87ce8919e to your computer and use it in GitHub Desktop.
Save fruitcoder/e3895060644d35b1b7c55bb87ce8919e to your computer and use it in GitHub Desktop.
Adding loading and reloading UI to everything owning a UIView
````
import UIKit
import Foundation
public protocol LoadStateIndicating {
/// Shows a blur view over the current context with an animated activity indicator.
func startLoading()
/// Hides blur view and activity indicator.
func stopLoading()
/// Shows reload option over blur view.
func showReload(onReloadTarget: Any?, action: Selector)
/// Hides reload option from blur view. Call `stopLoading()` to hide blur view altogether.
func hideReload()
}
public protocol ContentPresenter: LoadStateIndicating {
var mainView: UIView { get }
}
extension UIViewController: ContentPresenter {
public var mainView: UIView {
return self.view
}
}
extension UITableViewController {
public override var mainView: UIView {
return self.view.subviews.first ?? self.view
}
}
extension UICollectionViewController {
public override var mainView: UIView {
return self.view.subviews.first ?? self.view
}
}
extension UIView: ContentPresenter {
public var mainView: UIView {
return self
}
}
extension UITableViewCell {
public override var mainView: UIView {
return self.contentView
}
}
extension UICollectionViewCell {
public override var mainView: UIView {
return self.contentView
}
}
extension ContentPresenter {
public func startLoading() {
if let currentLoadingView = mainView.subviews.filter({ $0.tag == 101 }).first as? UIVisualEffectView, let activityView = currentLoadingView.contentView.subviews.first as? UIActivityIndicatorView {
activityView.startAnimating()
return
}
let activityView = UIActivityIndicatorView(activityIndicatorStyle: .white)
activityView.color = UIColor(red: 27/255.0, green: 161/255.0, blue: 232/255.0, alpha: 1.0)
activityView.hidesWhenStopped = true
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight))
blurView.tag = 101
blurView.contentView.addSubview(activityView)
mainView.addSubview(blurView)
blurView.translatesAutoresizingMaskIntoConstraints = false
blurView.widthAnchor.constraint(equalTo: mainView.widthAnchor).isActive = true
blurView.heightAnchor.constraint(equalTo: mainView.heightAnchor).isActive = true
blurView.centerXAnchor.constraint(equalTo: mainView.centerXAnchor).isActive = true
blurView.centerYAnchor.constraint(equalTo: mainView.centerYAnchor).isActive = true
activityView.translatesAutoresizingMaskIntoConstraints = false
activityView.centerXAnchor.constraint(equalTo: blurView.contentView.centerXAnchor).isActive = true
activityView.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor).isActive = true
activityView.startAnimating()
}
public func stopLoading() {
guard let blurView = mainView.subviews.filter({ $0.tag == 101 }).first as? UIVisualEffectView, let _ = blurView.contentView.subviews.first as? UIActivityIndicatorView else { return }
blurView.removeFromSuperview()
}
public func hideReload() {
guard let blurView = mainView.subviews.filter({ $0.tag == 101 }).first as? UIVisualEffectView, let _ = blurView.contentView.subviews.first as? UIActivityIndicatorView, let button = blurView.contentView.subviews[1] as? UIButton else { return }
button.removeFromSuperview()
}
public func showReload(onReloadTarget target: Any?, action: Selector) {
guard let blurView = mainView.subviews.filter({ $0.tag == 101 }).first as? UIVisualEffectView, let activityIndicator = blurView.contentView.subviews.first as? UIActivityIndicatorView else { return }
activityIndicator.stopAnimating()
let button = UIButton()
button.setTitle("Retry", for: .normal)
button.setTitleColor(.white, for: .normal)
button.backgroundColor = UIColor(red: 27/255.0, green: 161/255.0, blue: 232/255.0, alpha: 1.0)
button.layer.cornerRadius = 3.0
button.addTarget(target, action: action, for: .touchUpInside)
blurView.contentView.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: blurView.contentView.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor).isActive = true
}
}
````
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment