IOS:UITableView 上的 ActivityIndicator ......如何?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10363128/
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
IOS: ActivityIndicator over UITableView... How to?
提问by Tom
i want display an activity indicator over a uitableview while it's loading data (in another thread). So in the ViewDidLoad method of the UITableViewController:
我想在加载数据时(在另一个线程中)在 uitableview 上显示一个活动指示器。所以在 UITableViewController 的 ViewDidLoad 方法中:
-(void)viewDidLoad
{
[super viewDidLoad];
//I create the activity indicator
UIActivityIndicatorView *ac = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[ac startAnimating];
//Create the queue to download data from internet
dispatch_queue_t downloadQueue = dispatch_queue_create("PhotoDownload",NULL);
dispatch_async(downloadQueue, ^{
//Download photo
.......
.......
dispatch_async(dispatch_get_main_queue(), ^{
......
......
[ac stopAnimating];
});
});
.......
Why the activity indicator don't display over the table view? How can i achieve it?
为什么活动指示器不显示在表格视图上?我怎样才能实现它?
回答by bbarnhart
You need to add the UIActivityIndicatorView to something. You can add it to a UITableView header view. To do this you will need to provide your own custom view.
您需要将 UIActivityIndicatorView 添加到某些内容中。您可以将其添加到 UITableView 标题视图中。为此,您需要提供自己的自定义视图。
...
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
[view addSubview:ac]; // <-- Your UIActivityIndicatorView
self.tableView.tableHeaderView = view;
...
回答by zirinisp
I have been trying to find a solution for that and have read a lot of forums, but i did not get what I wanted. After understanding how the activity indicator and table view controller works I came up with the following solution.
我一直试图找到解决方案并阅读了很多论坛,但我没有得到我想要的。在了解活动指示器和表视图控制器的工作原理后,我想出了以下解决方案。
For some reason if you try to start the activity indicator on the same thread with the tableReload or any other expensive process, the activity indicator never runs. If you try to run table reload or some other operation in another thread then it might not be safe and might produce error or unwanted results. So we can run the method that presents the activity indicator on another thread.
出于某种原因,如果您尝试使用 tableReload 或任何其他昂贵进程在同一线程上启动活动指示器,则活动指示器永远不会运行。如果您尝试在另一个线程中运行 table reload 或其他一些操作,那么它可能不安全并且可能会产生错误或不需要的结果。所以我们可以在另一个线程上运行显示活动指示器的方法。
I have also combined this solution with the MBProgressHUD to present something that look nicer that a view with an activity indicator. In any case the looks of the activityView can be customized.
我还将这个解决方案与 MBProgressHUD 结合起来,呈现出比带有活动指示器的视图更好看的东西。在任何情况下,activityView 的外观都可以自定义。
-(void)showActivityViewer
{
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
UIWindow *window = delegate.window;
activityView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, window.bounds.size.width, window.bounds.size.height)];
activityView.backgroundColor = [UIColor blackColor];
activityView.alpha = 0.5;
UIActivityIndicatorView *activityWheel = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(window.bounds.size.width / 2 - 12, window.bounds.size.height / 2 - 12, 24, 24)];
activityWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
activityWheel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
[activityView addSubview:activityWheel];
[window addSubview: activityView];
[[[activityView subviews] objectAtIndex:0] startAnimating];
}
-(void)hideActivityViewer
{
[[[activityView subviews] objectAtIndex:0] stopAnimating];
[activityView removeFromSuperview];
activityView = nil;
}
- (IBAction)reloadDataAction:(id)sender {
[NSThread detachNewThreadSelector:@selector(showActivityViewer) toTarget:self withObject:nil];
//... do your reload or expensive operations
[self hideActivityViewer];
}
回答by MatthiasFranz
[iOS 5 +]
If you just want to show the activityWheel without an additional parentview, you can also add the activityWheel straight to the tableView and calculate the y value for the frame using the tableViews contentOffset:
【iOS 5 +】
如果只想显示activityWheel,不需要额外的parentview,也可以直接将activityWheel添加到tableView中,使用tableViews的contentOffset计算frame的y值:
@interface MyTableViewController ()
@property (nonatomic, strong) UIActivityIndicatorView *activityView;
@end
// ....
- (void) showActivityView {
if (self.activityView==nil) {
self.activityView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
[self.tableView addSubview:self.activityView];
self.activityView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
self.activityView.hidesWhenStopped = YES;
// additional setup...
// self.activityView.color = [UIColor redColor];
}
// Center
CGFloat x = UIScreen.mainScreen.applicationFrame.size.width/2;
CGFloat y = UIScreen.mainScreen.applicationFrame.size.height/2;
// Offset. If tableView has been scrolled
CGFloat yOffset = self.tableView.contentOffset.y;
self.activityView.frame = CGRectMake(x, y + yOffset, 0, 0);
self.activityView.hidden = NO;
[self.activityView startAnimating];
}
- (void) hideActivityView {
[self.activityView stopAnimating];
}
If the activityView doesn't show up immediately (or never), refer to zirinisp's answer or do the heavy work in the background.
如果 activityView 没有立即(或从不)出现,请参考 zirinisp 的回答或在后台进行繁重的工作。
回答by DianeZhou
There's workaround for UIViewController. (You can use a UIViewController with a table view to achieve a UITableViewController.) In storyboard, add a activityIndicator in the view of UIViewController. Then in viewDidLoad, add following:
有解决方法的UIViewController。(你可以使用带有表格视图的 UIViewController 来实现 UITableViewController。) 在 storyboard 中,在 UIViewController 的视图中添加一个 activityIndicator。然后在 viewDidLoad 中,添加以下内容:
[self.activityIndicator layer].zPosition = 1;
The activityIndicator will be displayed over the table view.
该activityIndicator将在表视图中显示。
回答by Werner Kratochwil
Although the question, is rather old, I add mine as well. [IOS 8+] The above does not work for me. Instead I store the indicator view (ac) in the class. Then I do:
虽然这个问题很老,但我也添加了我的。[IOS 8+] 以上对我不起作用。相反,我将指标视图 (ac) 存储在类中。然后我这样做:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (ac.isAnimating)
return 50.0f;
return 0.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (ac.isAnimating)
return ac;
return nil;
}
For showing the indicatorview I do
为了显示我做的指标视图
[ac startAnimating]
For hiding it, I do
为了隐藏它,我做
[ac stopAnimating]
I hope this is of help to someone.
我希望这对某人有帮助。