Je travaille avec une application qui analyse un flux en ligne. Lorsque je clique sur le bouton d'actualisation, il faut un certain temps pour analyser à nouveau le fichier et afficher ses données. Je veux un indicateur d'activité au milieu de la vue lorsque je clique sur le bouton d'actualisation. et lorsque l'analyse est terminée, cet indicateur doit se cacher. J'utilise ce code mais il ne fonctionne pas.
- (IBAction)refreshFeed:(id)sender
{
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.view addSubview:spinner];
[spinner startAnimating];
// parsing code code
[spinner release];
}
Un UIActivityIndicator doit généralement être placé dans un thread distinct du processus long (flux d'analyse) pour apparaître.
Si vous voulez tout conserver dans le même fil, vous devez donner le temps à l'indicateur d'apparaître. Cette question Stackoverflow adresse les adresses en retardant le code.
EDIT: Deux ans plus tard, je pense que chaque fois que vous utilisez un délai pour que quelque chose se produise, vous le faites probablement mal. Voici comment je voudrais faire cette tâche maintenant:
- (IBAction)refreshFeed:(id)sender {
//main thread
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; [self.view addSubview:spinner];
//switch to background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
//back to the main thread for the UI call
dispatch_async(dispatch_get_main_queue(), ^{
[spinner startAnimating];
});
// more on the background thread
// parsing code code
//back to the main thread for the UI call
dispatch_async(dispatch_get_main_queue(), ^{
[spinner stopAnimating];
});
});
}
Je pense que je ne suis pas capable de l'expliquer well.ok permet de réessayer. c'est un nav application basée. j'ai tableView. chaque cellule crée un detailView. sur RootView qui est une tableview il y a un bouton d'actualisation. quand je clique dessus bouton il analyse à nouveau le flux. et ça prend du temps. pour cette époque programme ne répond pas. et l'analyse est complète cela fonctionne à nouveau. maintenant j'ai besoin indicateur d'activité pour cette période. je ne sais pas comment ajouter dans xib. bcz quand J'ouvre main.xib et mets l'activité indicateur dans RootViewController. il vient en face de la table entière. à présent peut-être que j'ai bien expliqué. sinon laissez-moi sais que je vais essayer à nouveau.
d'après ce que vous dites ci-dessus, le programme ne répond pas pendant l'analyse, ce qui pose problème. Si l'interface graphique se fige pendant l'analyse des données, vous devez déplacer cette opération vers un thread secondaire. De cette façon, votre interface graphique reste réactive et vous pourrez voir l'indicateur d'activité.
sur le fil principal, vous devriez avoir quelque chose de similaire à ceci pour afficher l'indicateur d'activité:
UIActivityIndicatorView *av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
av.frame = CGRectMake(round((yourView.frame.size.width - 25) / 2), round((yourView.frame.size.height - 25) / 2), 25, 25);
av.tag = 1;
[yourView addSubview:av];
[av startAnimating];
une fois le fil secondaire terminé, c’est le fil sur lequel vous analysez les données. Vous devez appeler sur le fil principal quelque chose comme ceci pour supprimer le code d’activité:
UIActivityIndicatorView *tmpimg = (UIActivityIndicatorView *)[yourView viewWithTag:1];
[tmpimg removeFromSuperview];
Changer le centre de l'indicateur d'activité comme
activityIndicator.center = self.view.center;
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.alpha = 1.0;
[collectionVwSearch addSubview:activityIndicator];
activityIndicator.center = CGPointMake([[UIScreen mainScreen]bounds].size.width/2, [[UIScreen mainScreen]bounds].size.height/2);
[activityIndicator startAnimating];//to start animating
Pour Swift
let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
activityIndicator.alpha = 1.0
collectionVwSearch.addSubview(activityIndicator)
activityIndicator.center = CGPointMake(UIScreen.mainScreen().bounds.size.width / 2, UIScreen.mainScreen().bounds.size.height / 2)
activityIndicator.startAnimating()
Pour arrêter activityIndicator wirte [activityIndicator stopAnimating]
à l'endroit approprié
self.activity.center = CGPointMake(self.view.bounds.size.width / 2.0f, self.view.bounds.size.height / 2.0f);
self.activity.autoresizingMask = (UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin);
Ajoutez ce code avant de commencer votre tâche:
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.view addSubview:spinner];
[spinner setFrame:CGRectMake((self.view.frame.size.width/2)-(spinner.frame.size.width/2), (self.view.frame.size.height/2)-(spinner.frame.size.height/2), spinner.frame.size.width, spinner.frame.size.height)];
[spinner startAnimating];
Après avoir terminé la tâche, ajoutez:
[spinner stopAnimating];
Dans Swift, cela a fonctionné pour mon application
let activity_view = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
activity_view.frame = CGRectMake(0.0, 0.0, 40.0,40.0)
activity_view.center = self.view.center
self.view.addSubview(activity_view)
activity_view.bringSubviewToFront(self.view)
activity_view.startAnimating()
Vous pouvez écrire Swift 4
let spinner = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
override func viewDidLoad() {
super.viewDidLoad()
spinner.backgroundColor = UIColor(white: 0, alpha: 0.2) // make bg darker for greater contrast
self.view.addSubview(spinner)
}
@IBAction func foodActionBtn(_ sender: Any) {
// start spinner
spinner.frame = self.view.frame // center it
spinner.startAnimating()
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = DispatchQueue.global(qos: .background)
backgroundQueue.async(execute: {
sleep(2)
self.spinner.stopAnimating()
})
}
Le problème avec certaines des autres réponses est qu'un nouvel indicateur d'activité est ajouté à chaque fois afin que les sous-vues commencent à s'empiler. Voici un exemple complet qui utilise uniquement une seule UIActivityIndicator
.
Voici le code complet du projet ci-dessus:
import UIKit
class ViewController: UIViewController {
// only using a single spinner instance
let spinner = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge)
override func viewDidLoad() {
super.viewDidLoad()
// setup spinner
spinner.backgroundColor = UIColor(white: 0, alpha: 0.2) // make bg darker for greater contrast
self.view.addSubview(spinner)
}
@IBAction func startSpinnerButtonTapped(sender: UIButton) {
// start spinner
spinner.frame = self.view.frame // center it
spinner.startAnimating()
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
// do something that takes a long time
sleep(2)
// stop spinner when background task finishes
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.spinner.stopAnimating()
})
})
}
}
/ create activity indicator
activityIndicator = [[UIActivityIndicatorView alloc]
initWithFrame:CGRectMake(0.0f, 0.0f, 20.0f, 20.0f)];
[activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhite];
...
[self.view addSubview:activityIndicator];
// release it
[activityIndicator release];
Une meilleure approche consisterait à ajouter indicatore sur xib et à le masquer/afficher selon vos besoins
spinner.center = self.view.center;
Pour afficher spinner de rootController, essayez:
[self.navigationController.visibleViewController.view addSubview:spinner];
ou
[self.navigationController.view addSubview:spinner];
essayez comme ça
activityIndicator.center = CGPointMake(160,240);