1

I have the following code:-

- (UICollectionViewCell *)collectionView:(UICollectionView       *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{// Dequeue a prototype cell and set the label to indicate the page
CustomCellCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SurveyCell" forIndexPath:indexPath];
currentQuestion = [finalQuestionArray objectAtIndex:indexPath.row];

return cell;

}

so on loading first cell, cellForItemAtIndexPath is called only once but on loading second cell cellForItemAtIndexPath is called twice and currentQuestion is updated with the question in third cell not with second cell. How can I solve this?

I have pagecontrol over the collection view. Here is the code for creating collection view and adding paging on it

-(void)createCollectionView{
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flowLayout.minimumLineSpacing = 0;
flowLayout.minimumInteritemSpacing = 0;

// Set up the collection view with no scrollbars, paging enabled
// and the delegate and data source set to this view controller
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
self.collectionView.showsHorizontalScrollIndicator = YES;
self.collectionView.backgroundColor = [UIColor clearColor];
self.collectionView.pagingEnabled = YES;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
// Register a prototype cell class for the collection view
[self.collectionView registerNib:[UINib nibWithNibName:@"CustomCellCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"SurveyCell"];

[self.view addSubview:self.collectionView];
[self createPaging];

}

-(void)createPaging{
// page control
CGFloat w = self.view.frame.size.width;
CGFloat h = self.view.frame.size.height;

// Set up the page control
CGRect frame = CGRectMake(0, h - 84, w, 60);
pageControl = [[UIPageControl alloc] initWithFrame:frame];

// Add a target that will be invoked when the page control is
// changed by tapping on it
[pageControl addTarget:self action:@selector(pageControlChanged:) forControlEvents:UIControlEventValueChanged];

// Set the number of pages to the number of pages in the paged interface
// and let the height flex so that it sits nicely in its frame
pageControl.numberOfPages = numberOfPages;
pageControl.pageIndicatorTintColor = [UIColor blueColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];
pageControl.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self.view addSubview:pageControl];

}

j.krissa
  • 223
  • 5
  • 21
  • I noticed that the issue is only on scrolling the collection view cell. Its fine on tapping the page control and when pageControlChanged: method is called. – j.krissa May 22 '17 at 14:30
  • 1
    Have you considered implementing `-[ scrollViewDidScroll:]` as a `UICollectionView` is a `UIScrollView` subclass? Then you should be able to get the current cell with `-[UICollectionView indexPathsForVisibleItems]` and update the page control. – Mats May 22 '17 at 15:04
  • @Mats yes I have already implemented- (void)scrollViewDidScroll:(UIScrollView *)_scrollView{ CGFloat viewWidth = _scrollView.frame.size.width; // content offset - tells by how much the scroll view has scrolled. int pageNumber = floor((_scrollView.contentOffset.x - viewWidth/50) / viewWidth) +1;pageControl.currentPage=pageNumber; }. but the issue is in cellForItemAtIndexPath.Its being called twice so the question object am getting is different from the one shown on the screen. Is it because of scrollview content size or width? and two cells are created??? – j.krissa May 23 '17 at 07:27
  • 1
    I don’t think you can expect `-[ collectionView:cellForItemAtIndexPath:]` to be called in a predictable manner. Especially if there are animations. Setting `currentQuestion` there is a bad idea. It would be better to set `currentQuestion` in `-[ scrollViewDidScroll:]`. – Mats May 23 '17 at 10:07
  • Thanks Mats this worked well and did fix the issue :)so now am setting currentQuestion in scrollview delegate method. but now how do you suggest to show the question on 0th index ?? as scrollviewDidScroll will be called only after scrolling to 1st index cell.Hence its showing null in 0th index – j.krissa May 23 '17 at 12:39
  • I referred [link](http://blog.learningtree.com/paging-with-collection-views-part-2/) for implementing Uicollection view with paging. I feel there is some error/issue in scrollview frame and cellForItemAtIndexPath being called. – j.krissa May 23 '17 at 12:54

2 Answers2

4

We should now expect some cells to be created (cellForItemAtIndexPath:) but never displayed in iOS 10. If for some wacky reason we didn't want this wonderful new behavior, we can set our collection view's isPrefetchingEnabled property to false (it defaults to true in iOS 10).

Hope this helps someone! :) you can refer below link [link]UICollectionView cellForItem called not correctly

j.krissa
  • 223
  • 5
  • 21
1
 -(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {


    CustomCellCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SurveyCell" forIndexPath:indexPath];


    for (int i = 0; i < finalQuestionArray.count; i++) {

                NSLog(@"index i %i", i);

                if (indexPath.item == i) {
                    currentQuestion = [finalQuestionArray objectAtIndex:i];


                 }
    }

    return cell;

}

Try this, maybe can solve your problem.

  • thanks for the logic! but my issue is cellForItemAtIndexPath is called twice and if I add this code, on swiping to the second cell- cellforrowatindexpath is called for index path{length = 2, path = 0 - 1} and {length = 2, path = 0 - 2} even without going to the third cell. – j.krissa May 23 '17 at 12:21
  • the issue exist only while scrolling from 0th index to 1st index. It works fine when I add a button on the cell which on clicking shows up the next cell with below code. -(void)nextButtonClicked:(UIButton*)nextButton{ pageControl.currentPage += 1; [self pageControlChanged:pageControl]; } – j.krissa May 23 '17 at 13:28
  • krissa i think you should check the current scroll offset to know if you have to load the survey 0. Like this example: if(scrollView.contentOffset.x < 60) {} else {} – Luca Fritz Ferrari May 23 '17 at 13:58
  • Didnt get you well – j.krissa May 23 '17 at 14:46