ios 如何以编程方式在视图中间创建活动指示器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5103227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:00:07  来源:igfitidea点击:

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

iosobjective-ccocoa-touchuiactivityindicatorview

提问by Piscean

I am working with an app which parses an feed online. when i click 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 its not working.

我正在使用一个在线解析提要的应用程序。当我单击刷新按钮时,重新解析文件并显示其数据需要一些时间。当我单击刷新按钮时,我希望在视图中间有一个活动指示器。解析完成后,该指示器应该隐藏。我正在使用此代码,但它不起作用。

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

   [spinner startAnimating];

   // parsing code code

   [spinner release];
}

回答by Walter

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

UIActivityIndi​​cator 通常需要从长进程(解析提要)放到一个单独的线程中才能出现。

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

如果你想把所有东西都放在同一个线程中,那么你需要给指示器时间出现。这个 Stackoverflow 问题解决了在代码中放置延迟的问题

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

回答by Sorin Antohi

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.

我想我无法很好地解释它。好吧,让我们再试一次。它是一个基于导航的应用程序。我有 tableView。每个单元格创建一个 detailView。在作为 tableview 的 RootView 上有一个刷新按钮。当我单击该按钮时,它会再次解析提要。这需要一些时间。那个时候程序没有响应。解析完成后,它又可以工作了。现在我需要那个时候的活动指示器。我不知道如何在xib中添加。bcz 当我打开 main.xib 并将活动指示器放在 RootViewController 中时。它出现在整个 tableView 的前面。现在可能我解释得很好。如果不让我知道我会再试一次。

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.

根据您上面所说的,程序在解析过程中没有响应,这是一个问题。如果在解析数据时 GUI 冻结,则应将该操作移至辅助线程。这样您的 GUI 保持响应,您将能够看到活动指示器。

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

回答by visakh7

Change the center of the activity indicator as

将活动指示器的中心更改为

activityIndicator.center = self.view.center;

回答by Hardik Thakkar

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

[activityIndicator stopAnimating]在适当的地方停止活动指示器写入

回答by Vaibhav Saran

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

回答by iphondroid

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

回答by Juan Carlos Moreno

In Swift, this worked for my app

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

回答by Suragch

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.

其他一些答案的问题是每次都会添加一个新的活动指示器,因此子视图开始堆积。这是一个仅使用单个UIActivityIndicator.

enter image description here

在此处输入图片说明

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

回答by Sameer Saif

You can write swift 4

你可以写 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()
    })
}

回答by xxcv

spinner.center = self.view.center;

To show spinner from rootController try:

要从 rootController 显示微调器,请尝试:

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

or

或者

[self.navigationController.view addSubview:spinner];