0

I have placed a UIProgressView in UITableViewCell. There are two issues I am facing :
1. UITableView scroll is getting hindered.
2. UIProgressView setProgress is called each time (obviously) which sets its progress each time it appears.

It is understandable that issue 1 occurs because of issue 2. To test this, I commented the UIProgressView in UITableViewCell. The scroll is so fast then.
This is the code for UIProgressView :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
        static NSString *CellIdentifier = @"Cell";

        SWTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil)
        {
            cell = [[SWTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            cell.backgroundColor =  [UIColor clearColor];

            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.accessoryType = UITableViewCellAccessoryNone;
            if ([cell respondsToSelector:@selector(layoutMargins)]) {
                cell.layoutMargins = UIEdgeInsetsZero;
                cell.preservesSuperviewLayoutMargins = false;
            }
        }
        else
        {
            NSArray *arr = [cell.contentView subviews];
            for(int i=0; i<[arr count]; i++)
            {
                UIView *view = [arr objectAtIndex:i];
                [view removeFromSuperview];
            }
        }

CustomerArticleDetail *customerArticleDetails = [arrDetails objectAtIndex:indexPath.row];  
...  
...  
UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
            [progressView setProgressTintColor:[UIColor colorWithRed:31.0/255 green:177.0/255 blue:137.0/255 alpha:1.0]];
            [[progressView layer]setCornerRadius:5.0f];
            [[progressView layer]setBorderWidth:2.0f];
            [[progressView layer]setMasksToBounds:TRUE];
            progressView.clipsToBounds = YES;
            [[progressView layer]setFrame:CGRectMake(50, 93, self.view.frame.size.width - 55, 8)];[[progressView layer]setBorderColor:[UIColor whiteColor].CGColor];

            progressView.trackTintColor = [UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:1.0];

            [progressView setProgress: ([customerArticleDetails.Logged_Hours floatValue]/[customerArticleDetails.Planned_Hours floatValue]) animated:YES];
            [cell.contentView addSubview:progressView]; 
...  
... 
return cell;
    }
Nitish
  • 13,845
  • 28
  • 135
  • 263
  • 1
    if you are using storyboard, add progressview to SWTableViewCell and make an outlet of it. Then you don't have to alloc init UIProgressView always in code. The initialisation and updates on progressview layer makes it slow to scroll. – Akhilrajtr Nov 03 '15 at 06:00

1 Answers1

0

It is always ban and wrong to add UIViews in cell each time they need to be rendered.

In this way you delete purpose of reusable cell, and scrolling is terrible. It is even costly to go through all subview each time and delete all subviews.
The way it should be done is that you create progress view once and then just refresh its progress if needed.

This is done in two ways.

  1. If you have your own costume cell :

Create UIProgress view in cell and just call set progress :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    SWTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[SWTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.backgroundColor =  [UIColor clearColor];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryType = UITableViewCellAccessoryNone;
        if ([cell respondsToSelector:@selector(layoutMargins)]) {
            cell.layoutMargins = UIEdgeInsetsZero;
            cell.preservesSuperviewLayoutMargins = false;
        }
    }

    // Animated YES is maybe a fine idea to be more nice, but it could be better if you use NO.
    [cell.progressView setProgress: ([customerArticleDetails.Logged_Hours floatValue]/[customerArticleDetails.Planned_Hours floatValue]) animated:YES]; 
}
  1. If you don't own the cell and you need to create view in this method.

Something like this :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    SWTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[SWTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.backgroundColor =  [UIColor clearColor];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryType = UITableViewCellAccessoryNone;
        if ([cell respondsToSelector:@selector(layoutMargins)]) {
            cell.layoutMargins = UIEdgeInsetsZero;
            cell.preservesSuperviewLayoutMargins = false;
        }

        UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
        [progressView setProgressTintColor:[UIColor colorWithRed:31.0/255 green:177.0/255 blue:137.0/255 alpha:1.0]];
        [[progressView layer]setCornerRadius:5.0f];
        [[progressView layer]setBorderWidth:2.0f];
        [[progressView layer]setMasksToBounds:TRUE];
        progressView.clipsToBounds = YES;
        [[progressView layer]setFrame:CGRectMake(50, 93, self.view.frame.size.width - 55, 8)];[[progressView layer]setBorderColor:[UIColor whiteColor].CGColor];

        progressView.trackTintColor = [UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:1.0];
        [progressView setTeg:10];
        [cell.contentView addSubview:progressView]; 
    }


    UIProgressView *progressView = [cell.contentView viewWithTag:0]


    // Animated YES is maybe a fine idea to be more nice, but it could be better if you use NO.
    [progressView setProgress: ([customerArticleDetails.Logged_Hours floatValue]/[customerArticleDetails.Planned_Hours floatValue]) animated:YES]; 
}

This way you create UIProgressview once (so no scrolling problem) and just setting progress on each cell separately.

Marko Zadravec
  • 8,298
  • 10
  • 55
  • 97