Adding UIActivityIndicator to UITableView

后端 未结 2 1529
情歌与酒
情歌与酒 2021-01-27 23:28

I need to load some data in a table view and while this is going on in the background I want to add an activity indicator in order to show that there is a process going on and w

2条回答
  •  失恋的感觉
    2021-01-27 23:52

    You can add a view which has a UIIndicatorView and a UILabel as your cell's subview. You can use this way to show error data loading/ error network/ empty data...

    Example:

    Your Controller can define two modes: UITableViewModeMessage and UITableViewModeData.

    In viewDidLoad, you set self.tableViewMode = UITableViewModeMessage. When has returned data, set self.tableViewMode = UITableViewModeData and reload data for tableview.

    Some code:

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

提交回复
热议问题