开发者

How can I create a activity indicator in middle of view programmatically?

I am working with an app which parses an feed online. When I click the refresh button, it takes some time to re parse the file and show 开发者_开发技巧its data. I want an activity indicator in the middle of the view when I click refresh button. And when parsing is done, that indicator should hide.

I am using this code but it is not working:

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

   [spinner startAnimating];

   // parsing code code
    
   [spinner release];
}


A UIActivityIndicator generally needs to be placed into a separate thread from the long process (parsing feed) in order to appear.

If you want to keep everything in the same thread, then you need to give the indicator time to appear. This Stackoverflow question addresses placing a delay in the code.

EDIT: Two years later, I think that any time you are using a delay to make something happen you are probably doing it wrong. Here is how I would do this task now:

- (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];
        });
    });
}


I think i am not able to explain it well.ok lets try again. its a nav based app. i have tableView. every cell creates a detailView. on RootView which is a tableview there is a refresh button. when i click that button it parses the feed again. and it takes some time. for that time program doesnt respond. and parsing is complete it works again. now i need activity indicator for that time. i dont know how to add in xib. bcz when i open main.xib and put activity indicator in RootViewController. it comes infront of whole tableView. now may be i explained well. if not let me know i ll try again.

from what you are saying above the program is not responding during the parsing which is a problem. If the GUI freezes while you are parsing the data you should move that operation to a secondary thread. That way your GUI remains responsive and you will be able to see the activity indicator.

on the main thread you should have something similar to this in order to show the activity indicator:

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

after the secondary thread is finished, this is the thread where you parse the data, you should call on the main thread something like this to remove the activity indicator:

UIActivityIndicatorView *tmpimg = (UIActivityIndicatorView *)[yourView viewWithTag:1];
[tmpimg removeFromSuperview];


Change the center of the activity indicator as

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

For 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()

To stop activityIndicator wirte [activityIndicator stopAnimating] on appropriate place


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


Add this code before starting your task:

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

After completion of the task add:

[spinner stopAnimating];


In Swift, this worked for my app

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


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

Better approach would be you add indicatore on xib & make it hide/unhide basedon your requirement


spinner.center = self.view.center;

To show spinner from rootController try:

[self.navigationController.visibleViewController.view addSubview:spinner];

or

[self.navigationController.view addSubview:spinner];


try like this

activityIndicator.center = CGPointMake(160,240);


The problem with some of the other answers is that a new activity indicator gets added every time so the subviews start piling up. Here is a complete example that only uses a single UIActivityIndicator.

How can I create a activity indicator in middle of view programmatically?

This is the entire code for the project above:

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


You can write 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()
    })
}


SWIFT 5

Declaration

let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView.init(style: UIActivityIndicatorView.Style.medium)
//if you want a bigger activity indicator, change style from .medium to .large

ViewDidLoad
activityIndicator.alpha = 1.0
view.addSubview(activityIndicator)
activityIndicator.center = view.center

Activate activity indicator, in my case it is in `didSelectRowAt` method
activityIndicator.startAnimating()

If you push to another viewController while animation is active, and then pop back, you will still see activity indicator animating, so you should do this

override func viewWillAppear(_ animated: Bool) {
        if activityIndicator.isAnimating {
            activityIndicator.stopAnimating()
        }
    }


Mr Poscean my code is working. But is you want show big appearing of activity indicator you can use it....

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜