0

In UIcollectionviewcell data is not loading in cell initially but cell's layout is loaded. When scrolled to the last cell and scrolled back it appears properly filled with data without any problem. I am getting the data from a json array. After getting json array i am reloading the collection view. I am using prototype cell in storyboard with autolayout. i have tried reloading using a button action but in that case only the visible cell is getting updated I am using flowlayout and horizontal scrolling this is my code for cellforitem

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

 UIImageView *img1=(UIImageView *)[cell viewWithTag:13];


 img1.image = [UIImage imageNamed:@"profile_pic.png"];

 if (![[[tableArray objectAtIndex:indexPath.row] valueForKey:@"img_extension"]isEqual:[NSNull null]]  ) {
    [img1 sd_setImageWithURL:[NSURL URLWithString:[[tableArray objectAtIndex:indexPath.row]valueForKey:@"img_extension"]] placeholderImage:nil completed:^(UIImage *image12, NSError *error, SDImageCacheType cachetype, NSURL *imageurl){

        if(error)
            img1 .image = nil;
        else
            img1 .image = image12;
        CGPoint saveCenter1 = img1.center;
        CGRect newFrame1 = CGRectMake(img1.frame.origin.x, img1.frame.origin.y,50, 50);
        img1.frame = newFrame1;
        img1.layer.cornerRadius = 50 / 2.0;
        img1.center = saveCenter1;
        img1.clipsToBounds = YES;
    }];
 }
 UILabel *lbl1=(UILabel *)[cell viewWithTag:1];
 UILabel *lbl2=(UILabel *)[cell viewWithTag:2];
 UILabel *lbl3=(UILabel *)[cell viewWithTag:3];
 UILabel *lbl4=(UILabel *)[cell viewWithTag:4];
 UILabel *lbl5=(UILabel *)[cell viewWithTag:5];
 UILabel *lbl6=(UILabel *)[cell viewWithTag:6];
 UILabel *lbl11=(UILabel *)[cell viewWithTag:11];
 UILabel *lbl12=(UILabel *)[cell viewWithTag:12];
 UITextView *txtvw = (UITextView *)[cell viewWithTag:7];
 lbl1.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"strong_hand"];
 lbl2.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"athleticism"];
 lbl3.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"stick_skills"];
 lbl4.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"dodging"];
 lbl5.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"shooting"];
 lbl6.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"lacrosse"];
 lbl11.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"instructor_name"];
 lbl12.text=@"INSTRUCTER";
 txtvw.text = [[tableArray objectAtIndex:indexPath.row]valueForKey:@"comment"];

 [cell layoutSubviews];
 return cell;
}
user3354805
  • 135
  • 8

2 Answers2

0

So im guessing here that tableArray have fixed size that is why it doesn't crash. If you are getting your cells without data, than probably you didn't provide that data properly. My bet is that at your first reload that tableArray is full of nils, or you are getting your JSON asynchronously and you didn't reload it on main thread (because you can update your views only on main). cellForItemAtIndexPath reloading only visible cells is working as intended it just needs data to do it. btw. your way of getting all properties and objects by tags and valueForKey is really scary :)

BigSzu
  • 271
  • 2
  • 8
  • The values in tablearray is not nil. I am sure of it because i have tried this in another way by passing the array from another class to this class and called [collectionview reload] in viewdidload before that i have 'nslog' the data and its showing the array values – user3354805 Nov 04 '15 at 08:27
  • Just put breaking point inside this method and test it normally. There are only 3 possibilities for this code to fail. 1. This method wasn't called at all after your reload (witch suggest problem with right way of calling reload) -> 2. Your tableArry is full of nils (at that time) -> 3. Your UILabels that you tryed to get by tags are nils (which is unlikely because they are used at some point). All other possibilities that i can thing of would crash your app. – BigSzu Nov 04 '15 at 08:54
  • The no of collection cells loaded is correct ie The no of values in tablearray Also code for collection view size is also called (no of values in array) and when putting break point in above code it is working normally(size of the collection view cell is same as screen size ). I have found a solution by calling the performSelector using delay and adding the collection reload in ` -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate ` – user3354805 Nov 04 '15 at 09:18
  • If delay helps you out, that just prove that i was spot on. You are loading your data asynchronously, and when you originally called reload, your data was still loading. – BigSzu Nov 04 '15 at 09:52
  • if that was the case then what was the problem when i was passing data from another class? – user3354805 Nov 04 '15 at 09:56
  • If you are loading your data asynchronously, then by means of dispatch or operation queues you are delegating your work to another thread. And if you are absolutely sure that you got all of your data before sending it to your collection then sweet you are 90% there. But you can not call your update from inside that thread, you need dispatch it to main. If that isn't what happened, then god help us all, because there is something wrong going one in the rest of that cod ;p. – BigSzu Nov 04 '15 at 10:23
0

Put a breakpoint at this line lbl2.text=[[tableArray objectAtIndex:indexPath.row]valueForKey:@"athleticism"]; and type this into the debugger console po [[tableArray objectAtIndex:indexPath.row]valueForKey:@"athleticism"] and hit enter. This will tell you whether there's data in your array.

If you get nil as a response, then see if the tableArray itself is nil po tableArray.

Also, why have you written your code in such an awful way? Why are you using viewWithTag on your cell object instead of creating properties being IBOutlets, so you could access them cell.titleLabel.text = ...? Why are you using objectForKey? Why not simply get a reference to the object MyClass* object = [tableArray objectAtIndex:indexPath.row]; and then use it lbl1.text = object.strong_hand;?

BR41N-FCK
  • 766
  • 6
  • 17