はじめに
通信実行中にLoadingを表示するということが多くありますが、
いちいちindicatorViewを作成してaddSubViewして表示するのは正直面倒です。
その辺りの処理を簡潔にするUIViewのExtensionを作成したのでメモします。
検証環境
以下の環境を使用しています。
- macOS High Sierra Version 10.13.4
- Xcode Version 9.4.1
実装
UIViewのExtensionにLoading表示用のメソッドと、非表示にするメソッドを作成しています。Loading表示中はViewの操作を行って欲しくないため、isUserInteractionEnabledをLoadingを表示するタイミングでdisableに変更し、Loadingを非表示に変更したタイミングでenableにしています。
UIViewを継承していれば使用できるため、UITableViewの各セルの情報を通信で取得する際や、画像の通信取得中などに対応可能です。
LoadingOverLayViewの内部のindicatorViewを別のクラス等に置き換えることで、Loading中の表示を変更できます。
副次的な効果として、Loading中の表示には本メソッドを使用するようにすれば、アプリ内でのloadingの表示を統一できます。
///表示用のIndicator本体 UIViewのExtension以外からの生成を防ぐためfileprivateにしています
fileprivate final class LoadingOverLayView: UIView {
// MARK: - Property
private var indicatorView: UIActivityIndicatorView!
// MARK: - LifeCycle
init(frame: CGRect, indicatorStyle: UIActivityIndicatorViewStyle) {
indicatorView = UIActivityIndicatorView(activityIndicatorStyle: indicatorStyle)
indicatorView.hidesWhenStopped = true
super.init(frame: frame)
addSubview(indicatorView)
indicatorView.center = center
backgroundColor = UIColor.black
alpha = 0.4
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Method
func startAnimation() {
indicatorView.startAnimating()
}
func stopAnimation() {
indicatorView.stopAnimating()
}
}
// MARK: - UIView Extension
extension UIView {
/// LoadingViewを表示します
///
/// - Parameter indicatorStyle: UIActivityIndicatorViewのstyle(gray, white, whiteLarge)
func showLoading(with indicatorStyle: UIActivityIndicatorViewStyle = .whiteLarge) {
// Loading中にはView操作をして欲しくないためユーザー操作を不可にしています
isUserInteractionEnabled = false
let overLayView = LoadingOverLayView(frame: frame, indicatorStyle: indicatorStyle)
addSubview(overLayView)
overLayView.startAnimation()
}
/// 表示されているIndicatorViewを非表示にします
func hideLoading() {
// Loadingを非表示にしたタイミングでユーザー操作を可能にしています
isUserInteractionEnabled = true
subviews.forEach { subView in
if let subView = subView as? LoadingOverLayView {
subView.stopAnimation()
subView.removeFromSuperview()
}
}
}
}