Created
December 2, 2016 11:09
-
-
Save fruitcoder/e3895060644d35b1b7c55bb87ce8919e to your computer and use it in GitHub Desktop.
Adding loading and reloading UI to everything owning a UIView
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
```` | |
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