IOS:UITableView上的ActivityIndicator。。。如何?
我希望在uitableview加载数据时(在另一个线程中)在其上显示活动指示器。因此,在UITableViewController的ViewDidLoad方法中:IOS:UITableView上的ActivityIndicator。。。如何?,ios,uitableview,uiactivityindicatorview,Ios,Uitableview,Uiactivityindicatorview,我希望在uitableview加载数据时(在另一个线程中)在其上显示活动指示器。因此,在UITableViewController的ViewDidLoad方法中: -(void)viewDidLoad { [super viewDidLoad]; //I create the activity indicator UIActivityIndicatorView *ac = [[UIActivityIndicatorView alloc]
-(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];
});
});
.......
为什么活动指示器不显示在表视图上?如何实现它?您需要将UIActivityIndicatorView添加到某些内容中。可以将其添加到UITableView标题视图中。为此,您需要提供自己的自定义视图
...
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
[view addSubview:ac]; // <-- Your UIActivityIndicatorView
self.tableView.tableHeaderView = view;
...
。。。
UIView*view=[[UIView alloc]initWithFrame:CGRectMake(0,0320,50)];
[视图添加子视图:ac];// 我一直在试图找到一个解决方案,并阅读了很多论坛,但我没有得到我想要的。在了解活动指示器和表视图控制器的工作原理后,我提出了以下解决方案
出于某种原因,如果尝试在tableReload或任何其他昂贵进程的同一线程上启动活动指示器,则活动指示器将永远不会运行。若您试图在另一个线程中运行表重载或其他操作,那个么它可能不安全,并且可能会产生错误或不需要的结果。因此,我们可以在另一个线程上运行表示活动指示器的方法
我还将此解决方案与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];
}
[iOS 5+]
如果只想在不显示其他父视图的情况下显示activityWheel,还可以将activityWheel直接添加到tableView中,并使用tableViews contentOffset计算帧的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];
}
如果activityView没有立即显示(或从未显示),请参考zirinisp的答案或在后台执行繁重的工作。UIViewController有解决方法。(可以将UIViewController与表视图一起使用,以实现UITableViewController。)
在情节提要中,在UIViewController视图中添加activityIndicator。
然后在viewDidLoad中添加以下内容:
[self.activityIndicator layer].zPosition = 1;
活动指示器将显示在表视图上。[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;
}
为了显示指示灯视图,我做了
[ac startAnimating]
因为我把它藏起来了
[ac stopAnimating]
我也对这个问题感兴趣。但据我所知,UIView子类不是线程安全的。快动手吧+答案是1。活动指示器是UIView,因此需要以某种方式将其添加到视图层次结构中!在将ac living添加到新创建的视图之前,它在哪里?在经过几个选择之后,这对我来说非常有效。谢谢@zirinisp!我已经搜索了很长一段时间了,我必须说这是目前为止最好的解决方案。这是可行的,但我如何将其移动到一个帮助器类中,以便调用任何视图?创建一个包含上述方法的类别这似乎非常危险。UI操作必须在主线程上进行(即至少添加和删除子视图)。此外,鉴于showActivityViewer和hideActivityViewer在两个不同的线程上运行,任何数量的争用条件都可能发生(例如,可以在window addSubview之前调用hideActivityViewer,并且所有争用条件都会发生)。