Lorsque je change d’onglet, cela charge quelques secondes et je veux savoir que mes données se chargent. Pour cela, j'ai décidé d'ajouter un indicateur d'activité.
J'ai écrit une petite fonction:
func showActivityIndicator() {
dispatch_async(dispatch_get_main_queue()) {
self.spinner = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge)
self.spinner.frame = CGRect(x: 0.0, y: 0.0, width: 80.0, height: 80.0)
self.spinner.center = CGPoint(x:self.loadingView.bounds.size.width / 2, y:self.loadingView.bounds.size.height / 2)
self.loadingView.addSubview(self.spinner)
self.view.addSubview(self.loadingView)
self.spinner.startAnimating()
}
}
cela montrera mon indicateur. Et essayez de l'utiliser quand j'ai tapé sur mon infoController pour le bouton:
@IBAction func goToMainFromInfo(sender: AnyObject) {
self.showActivityIndicator()
self.performSegueWithIdentifier("fromMainToInfoWActivity", sender: nil)
self.hideActivityIndicator()
}
}
Je le montre avant segue effectuer et se cacher après. Ça ne m'aide pas Quand j'ai essayé d'utiliser la synchronisation:
@IBAction func goToMainFromInfo(sender: AnyObject) {
dispatch_async(dispatch_get_main_queue()) {
self.showActivityIndicator()
self.performSegueWithIdentifier("fromMainToInfoWActivity", sender: nil)
self.hideActivityIndicator()
}
}
Mais cela n'aide pas trop. Lorsque j'appuie sur l'onglet, l'opacité devient 0.5 et j'attends pendant le chargement. Mais je ne vois pas mon indicateur d'activité.
Quel est le problème?
Essayez ceci:
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)
}
Et où vous voulez commencer à animer
indicator.startAnimating()
indicator.backgroundColor = UIColor.whiteColor()
Pour arrêter:
indicator.stopAnimating()
indicator.hidesWhenStopped = true
Remarque: Évitez d'appeler Start et Stop en même temps. Donnez juste quelques conditions.
Swift 2+
class ViewController: UITableViewController {
weak var activityIndicatorView: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
tableView.backgroundView = activityIndicatorView
self.activityIndicatorView = activityIndicatorView
activityIndicatorView.startAnimating()
}
...
}
Rapide
Placez ceci en dessous de votre classe:
let indicator:UIActivityIndicatorView = UIActivityIndicatorView (activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
Placez ceci dans votre loadView ():
indicator.color = UIColor .magentaColor()
indicator.frame = CGRectMake(0.0, 0.0, 10.0, 10.0)
indicator.center = self.view.center
self.view.addSubview(indicator)
indicator.bringSubviewToFront(self.view)
indicator.startAnimating()
Dans mon cas, je demande des objets json via une requête func, je l'ai donc placée à la fin de cette fonction pour supprimer l'indicateur d'activité une fois les données chargées:
self.indicator.stopAnimating()
self.indicator.hidesWhenStopped = true
Une autre approche, dans mon code, j’ai ajouté une extension pour UITableView (Swift 2.3):
extension UITableView {
func activityIndicator(center: CGPoint = CGPointZero, loadingInProgress: Bool) {
let tag = 12093
if loadingInProgress {
var indicator = UIActivityIndicatorView()
indicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 40, 40))
indicator.tag = tag
indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
indicator.color = //Your color here
indicator.center = center
indicator.startAnimating()
indicator.hidesWhenStopped = true
self.superview?.addSubview(indicator)
}else {
if let indicator = self.superview?.viewWithTag(tag) as? UIActivityIndicatorView { {
indicator.stopAnimating()
indicator.removeFromSuperview()
}
}
}
}
Remarque: Ma vue de table est intégrée à UIView (superview).
Ce code peut vous aider :)
let indicator:UIActivityIndicatorView = UIActivityIndicatorView (activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
indicator.color = UIColor .magentaColor()
indicator.frame = CGRectMake(0.0, 0.0, 10.0, 10.0)
indicator.center = self.view.center
self.view.addSubview(indicator)
indicator.bringSubviewToFront(self.view)
indicator.startAnimating()
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
}
Afin de placer UIActivityIndicator au premier plan, même par-dessus les éventuels séparateurs UITableViewController, j'ai adopté cette solution.
J'ai ajouté le UIActivityIndicator par programmation, et l'ajouté comme sous-vue de mon UINavigationController
var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
// Code
// .... omissis
// Set activity indicator
activityIndicator = UIActivityIndicatorView(style: .whiteLarge)
activityIndicator.color = UIColor.darkGray
activityIndicator.center = tableView.center
activityIndicator.hidesWhenStopped = true
activityIndicator.stopAnimating()
self.navigationController?.view.addSubview(activityIndicator)
}
Je viens juste de le démarrer et de l'arrêter en cas de besoin (dans mon cas):
func animateActivityIndicator(_ sender: Any ) {
guard let vc = sender as? UIViewController else { return }
if let v = vc as? MyTableViewController {
if v.activityIndicator.isAnimating {
v.activityIndicator.stopAnimating()
} else {
v.activityIndicator.startAnimating()
}
}
// Others UIViewController or UITableViewController follows...
// all of them exhibits an activityIndicator variable
// implemented programmatically or with the storyboard
}
PS. Mon environnement est Xcode 10.0, iOS 12.0
Utilisation de "lazy var". C'est mieux que la fonction
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
}()
Il suffit de démarrer le spinner n'importe où
comme ça
func requestData() {
// Request something
activityIndicatorView.startAnimating()
}