-2

I have a collection view in my project with lots of data coming from a web service. When I scroll the collection view vertically, it doesn't scroll smoothly.

I used SDWebImage to load the images asynchronously.

Here is the code of cellForItemAtIndexPath:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CategoryListCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CategoryListCell" forIndexPath:indexPath];

    cell.movName.text = [nameArray objectAtIndex:indexPath.item];

    num = [[numArray objectAtIndex:indexPath.item]integerValue];
    cell.itemNo.text = [NSString stringWithFormat:@"%ld", (long)num];


    [cell.movImage sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",[imageArray objectAtIndex:indexPath.item]]] placeholderImage:[UIImage imageNamed:@"Main_Logo.png"]];
    [cell.movImage setShowActivityIndicatorView:YES];
    [cell.movImage setIndicatorStyle:UIActivityIndicatorViewStyleWhite];

    return cell;
}

When I run the project on Simulator it scrolls smoothly but when run it on Physical Device it does not scroll smoothly. How can I solve this?

MUNNA
  • 25
  • 9
  • I suggest you use the time profiler Instrument – Paulw11 Aug 22 '17 at 06:24
  • I think you dont need for loop in cellForItemAt method, just use num = [[numArray objectAtIndex:indexPath.item]integerValue]; cell.itemNo.text = [NSString stringWithFormat:@"%ld", (long)num]; without any for loop – 3stud1ant3 Aug 22 '17 at 06:26
  • I already used that but doesn't found any solution Paul. – MUNNA Aug 22 '17 at 06:27
  • try removing the loop, check the @user1000 comment – Reinier Melian Aug 22 '17 at 06:33
  • I used your code but it doesn't scroll smoothly in iPad. @Reinier – MUNNA Aug 22 '17 at 06:35
  • It's not going to have a material impact on performance, but don't instantiate a blank cell only to replace it with a dequeued one. Reduce those two lines to just `CategoryListCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CategoryListCell" forIndexPath:indexPath];`. – Rob Aug 22 '17 at 06:36
  • How big are these images? Are they appropriately sized for the image view? If you have huge images that are dynamically scaled for the image view, that can cause slightly stuttering in the scrolling (not because of the download time, but rather the dynamic resizing of the image). Also, are you doing anything of note within `CategoryListCell`, or is it just these three `IBOutlet` references? – Rob Aug 22 '17 at 06:37
  • Yes the images are perfect for ImageView cause on iPhone it works good. – MUNNA Aug 22 '17 at 06:42
  • There's nothing here in the code you've shared with us that would cause it to not scroll smoothly (esp if you've removed that `for` loop). And you're testing this (a) on a device; and (b) a release build without any diagnostic settings in the scheme settings, right? I wonder if you might just have something else running that could be blocking the main queue. – Rob Aug 22 '17 at 06:45
  • Yes. But It actually runs good on simulator not in Device. If you have any solution for this please give me. – MUNNA Aug 25 '17 at 10:35

3 Answers3

2

The for loop looks like the culprit, based on how big it is. SDWebImage takes care of doing operations on background thread, so that should be okay.

However, do a profiling of the method collectionView:cellForRowAtIndexPath: and figure out time it takes to render each cell. If it is more than 0.016 seconds - it is the reason for the delay in your performance. Below is the code that you can quickly use to measure the performance of cell rendering.

NSDate *methodStart = [NSDate date];

CategoryListCell *cell = [[CategoryListCell alloc]init];
cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CategoryListCell" forIndexPath:indexPath];

cell.movName.text = [nameArray objectAtIndex:indexPath.item];

for (int i=0; i<=numArray.count; i++)
{
    num = [[numArray objectAtIndex:indexPath.item]integerValue];
    cell.itemNo.text = [NSString stringWithFormat:@"%ld", (long)num];
}


[cell.movImage sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",[imageArray objectAtIndex:indexPath.item]]] placeholderImage:[UIImage imageNamed:@"Main_Logo.png"]];
[cell.movImage setShowActivityIndicatorView:YES];
[cell.movImage setIndicatorStyle:UIActivityIndicatorViewStyleWhite];

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

For more details on quick profiling of this method, check this: How to log a method's execution time exactly in milliseconds?

prabodhprakash
  • 3,825
  • 24
  • 48
  • Would it be possible for you to post a gif or something that shows the scroll performance and can you post more code around this UICollectionView? – prabodhprakash Aug 22 '17 at 06:58
0

I think, you mistake line code for.Therefore, It will not smooth in collectionView. You set it under background or You can calculate it outside function cellForItemAtIndexPath.

0

I don't really see much of problems. Couple things I want to point out.

  1. You are unnecessarily initiating collection view cell in cellForItemAtIndexPath. dequeueReusableCellWithReuseIdentifier: forIndexPath: will always return a cell.

  2. What does your for loop in cellForItemAtIndexPath do? It's setting itemNo text numArray count times. Am I misreading?

  3. Do you have round corner in movImage? Then try without round corner and see if you can see the difference. Rendering round corner is heavy.

HMHero
  • 2,333
  • 19
  • 11