Question

I want the tableview to display multiple images in each and every row which is scrollable. For this I'm using UITableView and Custom UITableViewCell, in custom tableView cell i'm generating scroll view with multiple views & images, So when i'm scrolling table its not scrolling smoothly its blinking. Can anyone suggest me to do this in better way?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
   // Products table view. 
   ProductCustomCell *cell = (ProductCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CatelogCell"] ;//] forIndexPath:indexPath]; 
   if (cell == nil) { 
      cell = [[ProductCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CatelogCell"]; 
   } 
   cell.productCellDelegate = self; 
   [cell initProperties]; 
   [cell showProductsInScroll:catelogBundle];
}
Was it helpful?

Solution

if you want to scroll tableview smooth, several tips you should pay attention.

  1. Cache the height of the rows (the table view can request this frequently), -- actually this point isn't the key point to block your tableview scroll.

  2. Create a least-recently-used cache for the images used in the table (and invalidate all the inactive entries when you receive a memory warning) -- you can use SDWebImage to download image and cache them. And sometimes, you maybe want to cache some images that your tableview frequently used and these images could also don't free even you receive a memory warning if your current view is the top view。

  3. Draw everything in the UITableViewCell's drawRect: if possible avoid subviews at all costs (or if you require the standard accessibility functionality, the content view's drawRect:) -- it could save some cost, but it also may cost your more time to code and maybe hard to maintain codes. But it is really good to use less views on uitableviewcell, that will improve your performance.

  4. Make your UITableViewCell's layer opaque (same goes for the content view if you have one) -- please use layer opaque as less as possible.

  5. Use the reusableCellIdentifier functionality as recommended by the UITableView examples/documentation -- you must follow this tips.

  6. Avoid gradients/complicated graphical effects that aren't pre-baked into UIImages -- like point 4.

of course, most time, if your tableview scroll not smooth, the main problem is that you load image in synchronize.

it's really good to use instruments to test the performance.

OTHER TIPS

You probably found a solution for your problem already, but if you're still looking, this worked for me. I'm also working on an app that involves displaying many pictures over several tableview cells.

I found out that the cellForRowAtIndexPath method is called pretty much every time the app loads a new cell onto the screen that is not already displayed, so every time you scroll up or down to new cells, this method keeps getting called even if some of the cells were on the screen earlier before you scrolled to a different position.

What I did was save cells and their corresponding indexpaths that were initialized for the first time into an array and when the cellForRowAtIndexPath method gets called again, check if this cell was already initialized by checking if the indexpath is stored in my array of indexpaths.

@implementation MyViewController{
    NSMutableArray *cells;
    NSMutableArray *indexpaths;
}

...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    // check if in array
    if ([indexpaths containsObject:indexPath]){
        return cells[indexPath.row];
    }

    // otherwise, create a new one
    UITableViewCell *cell = [[UITableViewCell alloc] init];

    // customizing cell
    // other stuff
    ...

    // finally save the cell and indepath for checking later
    [cells addObject:cell];
    [indexpaths addObject:indexPath];

    return cell;
}

I think the problem may be that you may be allocating objects in cellForRowAtIndexPath delegate method of UITableView . So instead of allocating any type of object there allocate in its ProductCustomCell class or create it in its xib file .

I would like add a simple method in addition to TinyMonk's answer. If you make uitableview using custom cell, then make sure the clip subview option ticked right both for table and custom cell. It worked for me.

Based on the solution of Leo C han, I have updated it for Swift3.

var manualCells = NSMutableArray()

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

   // check if in array
   if manualCells.contains(indexPath) {
      return manualCells.object(at: indexPath.row) as! UITableViewCell
   }

   let cell = self.tableViewReference.dequeueReusableCell(withIdentifier: "mainIdentifier") as! YourTableViewCell

   // fill the cell...     

   manualCells.insert(cell, at: indexPath.row)
   return cell
}

Note, this is for tables containing one section.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top