Добавление UIActivityIndicator в UITableView

Мне нужно загрузить некоторые данные в виде таблицы, и пока это происходит в фоновом режиме, я хочу добавить индикатор активности, чтобы показать, что процесс идет, и он будет скрыт после завершения процесса. Что было бы наиболее эффективным способом реализовать что-то подобное?


person Tim Stullich    schedule 31.07.2012    source источник


Ответы (2)


Зависит от того, хотите ли вы заблокировать своего пользователя или нет, а также насколько важна индикация активности.

Если вы не хотите блокировать пользователя, используйте Application.networkActivityIndicatorVisible, если вы хотите иметь больший индикатор активности и при этом не блокировать пользователя, анимируйте UIView с текстом и UIActivityIndicator под табличным представлением (tableview.height -= activityview.height), а затем скройте по завершении или если вы хотите например, чтобы заблокировать пользователя, используйте индикатор активности блокировки.

person Miro Hudak    schedule 31.07.2012
comment
Кстати, как вы добавили проект MBProgressHud в свое приложение? Каждый раз, когда я пытаюсь скомпилировать, я получаю ошибку компиляции. - person Tim Stullich; 01.08.2012
comment
Что за ошибка компиляции? Если вы используете ARC, вам необходимо отключить ARC для MBProgressHUD (TargetBuild PhasesCompile SourcesMBProgressHUD.m установить флаг компилятора -fno-objc-arc) - person Miro Hudak; 01.08.2012

Вы можете добавить представление с UIIndicatorView и UILabel в качестве подпредставления вашей ячейки. Вы можете использовать этот способ, чтобы показать загрузку данных об ошибках/сеть ошибок/пустые данные...

Пример:

Ваш контроллер может определить два режима: UITableViewModeMessage и UITableViewModeData.

В viewDidLoad вы устанавливаете self.tableViewMode = UITableViewModeMessage. Когда вернул данные, установите self.tableViewMode = UITableViewModeData и перезагрузите данные для просмотра таблицы.

Некоторый код:

- (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;
}
person Hoàng Toản    schedule 31.07.2012