When I switch between my tabs it loads some seconds and I want to know that my data is loading. For that I decided to add an activity indicator.
I wrote a little functio
I use two extension methods to add an UIActivityIndicatorView
as the backgroundView
of the tableview.
extension UITableView {
func showActivityIndicator() {
DispatchQueue.main.async {
let activityView = UIActivityIndicatorView(style: .medium)
self.backgroundView = activityView
activityView.startAnimating()
}
}
func hideActivityIndicator() {
DispatchQueue.main.async {
self.backgroundView = nil
}
}
}
You can show/hide it like this.
tableView.showActivityIndicator()
tableView.hideActivityIndicator()
Using "lazy var". It's better than function
fileprivate lazy var activityIndicatorView: UIActivityIndicatorView = {
let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
activityIndicatorView.hidesWhenStopped = true
// Set Center
var center = self.view.center
if let navigationBarFrame = self.navigationController?.navigationBar.frame {
center.y -= (navigationBarFrame.origin.y + navigationBarFrame.size.height)
}
activityIndicatorView.center = center
self.view.addSubview(activityIndicatorView)
return activityIndicatorView
}()
Just start the spinner anywhere
like this
func requestData() {
// Request something
activityIndicatorView.startAnimating()
}
Just try this:
var indicator = UIActivityIndicatorView()
func activityIndicator() {
indicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 40, 40))
indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
indicator.center = self.view.center
self.view.addSubview(indicator)
}
And where you want to start animating
indicator.startAnimating()
indicator.backgroundColor = UIColor.whiteColor()
For stop:
indicator.stopAnimating()
indicator.hidesWhenStopped = true
Note: Avoid the calling of start and stop at the same time. Just give some conditions.
SWIFT : 4.2 Just try this:
var indicator = UIActivityIndicatorView()
func activityIndicator() {
indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
indicator.style = UIActivityIndicatorView.Style.gray
indicator.center = self.view.center
self.view.addSubview(indicator)
}
And where you want to start animating
activityIndicator()
indicator.startAnimating()
indicator.backgroundColor = .white
For stop:
indicator.stopAnimating()
indicator.hidesWhenStopped = true
func setupSpinner(){
spinner = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height:40))
spinner.color = UIColor(Colors.Accent)
self.spinner.center = CGPoint(x:UIScreen.main.bounds.size.width / 2, y:UIScreen.main.bounds.size.height / 2)
self.view.addSubview(spinner)
spinner.hidesWhenStopped = true
}
Update Swift 4.2:
1.call the activityIndicator function on viewDidLoad
eg:
var indicator = UIActivityIndicatorView()
override func viewDidLoad() {
//Initializing the Activity Indicator
activityIndicator()
//Starting the Activity Indicator
indicator.startAnimating()
//Call Your WebService or API
callAPI()
}
Here is the Code For Adding ActivityIndicator as Subview
func activityIndicator() {
indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
indicator.style = UIActivityIndicatorView.Style.whiteLarge
indicator.color = .red
indicator.center = self.view.center
self.view.addSubview(indicator)
}
2. Do UI related Operations or API Call and stop activity indicator
func callAPI() {
YourModelClass.fetchResult(someParams,
completionHandler: { (response) in
//Do necessary UIUpdates
//And stop Activity Indicator
self.indicator.stopAnimating()
})
}
@brocolli's answer for swift 4.0. You have to use objc_ before getting or setting associated objects. According to the documentation, The APIs of getting and setting the associated object in Swift are:
func objc_getAssociatedObject(object: AnyObject!,
key: UnsafePointer<Void>
) -> AnyObject!
func objc_setAssociatedObject(object: AnyObject!,
key: UnsafePointer<Void>,
value: AnyObject!,
policy: objc_AssociationPolicy)
Implementation:
import UIKit
fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey"
extension UIView {
var activityIndicatorView: UIActivityIndicatorView {
get {
if let activityIndicatorView = objc_getAssociatedObject(self, &ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView {
return activityIndicatorView
} else {
let activityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
activityIndicatorView.activityIndicatorViewStyle = .gray
activityIndicatorView.color = .gray
activityIndicatorView.center = center
activityIndicatorView.hidesWhenStopped = true
addSubview(activityIndicatorView)
objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, activityIndicatorView, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return activityIndicatorView
}
}
set {
addSubview(newValue)
objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}