Как программно создать индикатор активности в центре зрения? - PullRequest
13 голосов
/ 24 февраля 2011

Я работаю с приложением, которое анализирует канал в Интернете.когда я нажимаю кнопку обновления, требуется некоторое время, чтобы проанализировать файл и показать его данныея хочу, чтобы индикатор активности находился в середине представления, когда я нажимал кнопку обновления.и когда анализ будет выполнен, этот индикатор должен скрыться.Я использую этот код, но он не работает.

- (IBAction)refreshFeed:(id)sender
{
   UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
   [self.view addSubview:spinner];

   [spinner startAnimating];

   // parsing code code

   [spinner release];
}

Ответы [ 13 ]

17 голосов
/ 24 февраля 2011

UIActivityIndicator, как правило, должен быть помещен в отдельный поток от длинного процесса (синтаксический анализ подачи), чтобы появиться.

Если вы хотите, чтобы все было в одном потоке, то вам нужно дать время индикатору появиться. Этот вопрос Stackoverflow посвящен размещению задержки в коде.

РЕДАКТИРОВАТЬ: Два года спустя, я думаю, что всякий раз, когда вы используете задержку, чтобы что-то произошло, вы, вероятно, делаете это неправильно. Вот как бы я выполнил эту задачу сейчас:

- (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];
        });
    });
}
12 голосов
/ 24 февраля 2011

Я думаю, что не могу объяснить это хорошо. Давайте попробуем еще раз.это приложение на основе навигации.у меня есть tableView.каждая ячейка создает detailView.на RootView, который является таблицей, есть кнопка обновления.когда я нажимаю эту кнопку, он снова анализирует канал.и это занимает некоторое время.за это время программа не отвечает.и разбор завершен, он снова работает.сейчас мне нужен индикатор активности на это время.я не знаю, как добавить в XIB.bcz когда я открываю main.xib и помещаю индикатор активности в RootViewController.это идет впереди всего tableView.Теперь, может быть, я объяснил хорошо.если нет, дайте мне знать, что я попробую снова.

из того, что вы говорите выше, программа не отвечает во время синтаксического анализа, что является проблемой.Если графический интерфейс зависает во время анализа данных, вы должны переместить эту операцию во вторичный поток.Таким образом, ваш графический интерфейс остается отзывчивым, и вы сможете увидеть индикатор активности.

в главном потоке у вас должно быть что-то похожее на это, чтобы показать индикатор активности:

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];

после завершения вторичного потока, это поток, в котором вы анализируете данные, вы должны вызвать в главном потоке что-то вроде этого, чтобы удалить индикатор активности:

UIActivityIndicatorView *tmpimg = (UIActivityIndicatorView *)[yourView viewWithTag:1];
[tmpimg removeFromSuperview];
7 голосов
/ 14 марта 2015
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

Для 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()

Для прекращения активности Индикатор wirte [activityIndicator stopAnimating] в соответствующем месте

7 голосов
/ 24 февраля 2011

Изменить центр индикатора активности на

activityIndicator.center = self.view.center;
2 голосов
/ 23 августа 2013
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);
1 голос
/ 20 февраля 2016

В Swift это работало для моего приложения

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()
1 голос
/ 05 ноября 2013

Добавьте этот код перед началом вашей задачи:

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];    

После завершения задания добавить:

[spinner stopAnimating];
0 голосов
/ 30 апреля 2018

Мистер Посчэн, мой код работает.Но если вы хотите показывать большое появление индикатора активности, вы можете использовать его ....

var activityIndicator = UIActivityIndicatorView()
    activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
    let transform: CGAffineTransform = CGAffineTransform(scaleX: 1.5, y: 1.5)
    activityIndicator.transform = transform
    activityIndicator.center = self.view.center
    activityIndicator.startAnimating()
    self.view.addSubview(activityIndicator)
0 голосов
/ 26 апреля 2018

Вы можете написать 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()
    })
}
0 голосов
/ 08 июля 2016

Проблема с некоторыми другими ответами заключается в том, что каждый раз добавляется новый индикатор активности, поэтому подпредставления начинают накапливаться.Вот полный пример, в котором используется только один UIActivityIndicator.

enter image description here

. Весь код для вышеуказанного проекта:

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()
            })
        })
    }
}
...