Loading an "overlay" when running long tasks in iOS
The above answers add a loading view but it doesn't block click events on the screen also it does not provides overlay for rest of screen. You can achieve it as follows:
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .Alert)alert.view.tintColor = UIColor.blackColor()let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(10, 5, 50, 50)) as UIActivityIndicatorViewloadingIndicator.hidesWhenStopped = trueloadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.GrayloadingIndicator.startAnimating();alert.view.addSubview(loadingIndicator)presentViewController(alert, animated: true, completion: nil)
Swift 3.0
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))loadingIndicator.hidesWhenStopped = trueloadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.grayloadingIndicator.startAnimating();alert.view.addSubview(loadingIndicator)present(alert, animated: true, completion: nil)
Swift 4.0 and newer
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))loadingIndicator.hidesWhenStopped = trueloadingIndicator.style = UIActivityIndicatorView.Style.grayloadingIndicator.startAnimating();alert.view.addSubview(loadingIndicator)present(alert, animated: true, completion: nil)
and you can hide it as follows:
dismiss(animated: false, completion: nil)
Just create yourself an overlay view, which you add to your parent view and remove it once your task is done, e.g. to add it:
var overlay : UIView? // This should be a class variable[ ... ]overlay = UIView(frame: view.frame)overlay!.backgroundColor = UIColor.blackColor()overlay!.alpha = 0.8view.addSubview(overlay!)
For removal:
overlay?.removeFromSuperview()
Blur background + Activity Indicator, Swift 5 example
extension UIView { func showBlurLoader() { let blurLoader = BlurLoader(frame: frame) self.addSubview(blurLoader) } func removeBluerLoader() { if let blurLoader = subviews.first(where: { $0 is BlurLoader }) { blurLoader.removeFromSuperview() } }}class BlurLoader: UIView { var blurEffectView: UIVisualEffectView? override init(frame: CGRect) { let blurEffect = UIBlurEffect(style: .dark) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = frame blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.blurEffectView = blurEffectView super.init(frame: frame) addSubview(blurEffectView) addLoader() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func addLoader() { guard let blurEffectView = blurEffectView else { return } let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50) blurEffectView.contentView.addSubview(activityIndicator) activityIndicator.center = blurEffectView.contentView.center activityIndicator.startAnimating() }}