将 UIActivityIndicator 添加到 UITableView
Posted
技术标签:
【中文标题】将 UIActivityIndicator 添加到 UITableView【英文标题】:Adding UIActivityIndicator to UITableView 【发布时间】:2012-07-31 19:52:31 【问题描述】:我需要在表格视图中加载一些数据,当这在后台进行时,我想添加一个活动指示器,以显示有一个进程正在进行,并在进程完成后隐藏。实现这样的事情最有效的方法是什么?
【问题讨论】:
【参考方案1】:取决于您是否要阻止您的用户,以及活动指示的重要性。
如果您不想阻止用户,请使用Application.networkActivityIndicatorVisible
,如果您想要更大的活动指示器但仍不阻止用户,请在表格视图下方使用文本和 UIActivityIndicator 为 UIView 设置动画 (tableview.height -= activityview.height
),然后隐藏完成或如果您想阻止用户,请使用阻止活动指示器。
【讨论】:
顺便问一下,您是如何将 MBProgressHud 项目添加到您的应用程序的?每次我尝试编译时都会出现编译错误。 什么样的编译错误?如果您使用 ARC,则必须为 MBProgressHUD 禁用 ARC (Target
> Build Phases
> Compile Sources
> MBProgressHUD.m
set compiler flag -fno-objc-arc
)【参考方案2】:
您可以添加一个具有 UIIndicatorView 和 UILabel 的视图作为单元格的子视图。您可以使用这种方式显示错误数据加载/错误网络/空数据...
例子:
您的控制器可以定义两种模式:UITableViewModeMessage 和 UITableViewModeData。
在 viewDidLoad 中,您设置 self.tableViewMode = UITableViewModeMessage。返回数据后,设置 self.tableViewMode = UITableViewModeData 并为 tableview 重新加载数据。
一些代码:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
if (self.tableViewMode == UITableViewModeMessage)
return 2;
else
return self.yourEntries ? self.yourEntries.count : 0;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if (self.tableViewMode == UITableViewModeMessage)
return [self tableView:tableView messageCellForRowAtIndexPath:indexPath];
else
return [self tableView:tableView dataCellForRowAtIndexPath:indexPath];
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
// Remove Loading... progress view if exist.
UIView *progressView = [cell viewWithTag:100];
[progressView removeFromSuperview];
if (self.tableViewMode == UITableViewModeMessage)
if (indexPath.row == 1)
// remove the current label.
cell.textLabel.text = nil;
// We build progress view and attach to cell here but not in cellForRowAtIndexPath is because in this method cell frame is already calculated.
UIView *progressView = [self progressViewForCell:cell message:@"Loading..." alpha:0.9];
[cell addSubview:progressView];
// cell to display when loading
- (UITableViewCell *)tableView:(UITableView *)tableView messageCellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"MessageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.textColor = [UIColor grayColor];
cell.textLabel.textAlignment = UITextAlignmentCenter;
if (indexPath.row == 1)
cell.textLabel.text = @"Loading...";
else
cell.textLabel.text = nil;
return cell;
// cell to display when has data
- (UITableViewCell *)tableView:(UITableView *)tableView dataCellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"DataCell";
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text = [[self.yourEntries objectAtIndex:indexPath.row] description];
return cell;
// Build a view which has a UIActivityIndicatorView and a UILabel
- (UIView *)progressViewForCell:(UITableViewCell *)cell message:(NSString *)message alpha:(CGFloat)alpha
// NOTE: progressView needs to be removed from cell in cellForRowAtIndexPath:
CGRect progressViewFrame = CGRectZero;
progressViewFrame.size.width = CGRectGetMaxX(cell.bounds);
progressViewFrame.size.height = CGRectGetMaxY(cell.bounds) - 2;
UIView *progressView = [[UIView alloc] initWithFrame:progressViewFrame];
progressView.backgroundColor = RGBA(255, 255, 255, 1);
progressView.alpha = alpha;
progressView.tag = 100;
UILabel *loadingLabel = [[UILabel alloc] initWithFrame:progressView.bounds];
loadingLabel.backgroundColor = [UIColor clearColor];
loadingLabel.font = [UIFont systemFontOfSize:14];
loadingLabel.textColor = [UIColor blackColor];
loadingLabel.textAlignment = UITextAlignmentCenter;
loadingLabel.text = message;
CGFloat widthOfText = [loadingLabel.text sizeWithFont:loadingLabel.font].width;
CGFloat spaceBetweenIndicatorAndLabel = 5;
// activityIndicatorView has size in which width and height is equal to 20.
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityIndicatorView setCenter:CGPointMake(CGRectGetMidX(cell.bounds) - (widthOfText / 2) - (activityIndicatorView.bounds.size.width / 2) - spaceBetweenIndicatorAndLabel, CGRectGetMidY(cell.bounds))];
[activityIndicatorView setColor:[UIColor blackColor]];
[activityIndicatorView startAnimating];
[progressView addSubview:activityIndicatorView];
[progressView addSubview:loadingLabel];
return progressView;
【讨论】:
以上是关于将 UIActivityIndicator 添加到 UITableView的主要内容,如果未能解决你的问题,请参考以下文章
将 UIActivityIndicator 添加到 UITableView
如何在 UITableView 的 searchBar 上方显示 UIActivityIndicator
在 Swift 中使用 UIActivityIndicator-for-SDWebImage
在 Swift 中使用 UIActivityIndicator-for-SDWebImage