user2037296
user2037296

Reputation: 421

cellForRowAtIndexPath doesn't get called after calling reloadData in UICollectionView

I have a UICollectionView which uses a subclass of UICollectionViewCell's. Initially, my dataSource contains 5 items, and when the user scrolls down, I fetch more data and add them to my dataSource, then I call reloadData.

But only 3 items are visible. and when I scroll up I can't see the rest of the items, just an empty area. I noticed that cellForRowAtIndexPath only gets called for those 3 items.

When I navigate to my parent view, and back to the view which contains my UICollectionView I can see all the items.

Note: I have implemented layout:sizeForItemAtIndexPath function as each cell has a different size.

Edit:

I partially solved the issue. I had a refreshControl and I called endRefreshing in a background thread.

Am adding images for a better demonstration of what's happening now:

enter image description here

enter image description here

enter image description here

After I finish loading new items, I call this method

- (void)updateDataSource
{
   self.collectionViewDataSource = _manager.messages;
   [self.collectionView reloadData];
}

I checked numberOfItemsInSection method, it returns the right number of items.

and here is my layout:sizeForItemAtIndexPath

- (CGSize)collectionView:(UICollectionView *)collectionView layout:   (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:  (NSIndexPath *)indexPath 
{
// Here I am calculating the width and height of the textView which will fit the message

SPH_PARAM_List *feed_data=[[SPH_PARAM_List alloc]init];
feed_data=[self.collectionViewDataSource objectAtIndex:indexPath.row];

if ([feed_data.chat_media_type isEqualToString:kSTextByme]||[feed_data.chat_media_type isEqualToString:kSTextByOther])
{

    NSAttributedString *aString = [[NSAttributedString alloc] initWithString:feed_data.chat_message];

    UITextView *calculationView = [[UITextView alloc] init];
    [calculationView setAttributedText:aString];

    [calculationView setFont:[UIFont systemFontOfSize:14]];
    [calculationView setTextAlignment:NSTextAlignmentJustified];


    CGSize sc = [calculationView sizeThatFits:CGSizeMake(TWO_THIRDS_OF_PORTRAIT_WIDTH, CGFLOAT_MAX)];

    NSLog(@"IndexPath: %li Height: %f", (long)indexPath.row ,sc.height);

    return CGSizeMake(self.view.frame.size.width - (5 * 2), sc.height);

}

return CGSizeMake(self.view.frame.size.width - (5 * 2), 90);

}

Edit 2:

I noticed that layout:collectionViewLayoutsizeForItemAtIndexPath: gets called and it returns the right height, but cellForItemAtIndexPath still deals with an old one.

Upvotes: 2

Views: 2932

Answers (2)

Mike Welsh
Mike Welsh

Reputation: 808

You likely need to invalidate your layout so that the cell positions and heights get recalculated since simply reloading the data won't properly set the cell heights (since cells are reused).

- (void)updateDataSource
{
   self.collectionViewDataSource = _manager.messages;
   [self.collectionView reloadData];
   // Add this line.
   [self.collectionView.collectionViewLayout invalidateLayout];
}

Upvotes: 1

Anni S
Anni S

Reputation: 2026

Can't figure it out until you show code. However, I guess your data source is not updated. Just check it out, your DataSource should have fetched the data before reloadData. You can put Some log to check number of items before/after reloadData. This might help.

Upvotes: 0

Related Questions