【问题标题】:collectionView cellForItemAtIndexPath: called twicecollectionView cellForItemAtIndexPath:调用了两次
【发布时间】:2017-05-22 13:06:53
【问题描述】:

我有以下代码:-

- (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;

}

所以在加载第一个单元格时,cellForItemAtIndexPath 仅被调用一次,但在加载第二个单元格时,cellForItemAtIndexPath 被调用两次,并且 currentQuestion 使用第三个单元格中的问题而不是第二个单元格进行更新。我该如何解决这个问题?

我对集合视图拥有页面控制权。这是创建集合视图并在其上添加分页的代码

-(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];

}

【问题讨论】:

  • 我注意到问题仅在于滚动集合视图单元格。在点击页面控件和调用 pageControlChanged: 方法时很好。
  • 您是否考虑过将-[<UIScrollViewDelegate> scrollViewDidScroll:] 实现为UICollectionViewUIScrollView 的子类?然后你应该能够使用-[UICollectionView indexPathsForVisibleItems] 获取当前单元格并更新页面控件。
  • @Mats 是的,我已经实现了- (void)scrollViewDidScroll:(UIScrollView *)_scrollView{ CGFloat viewWidth = _scrollView.frame.size.width; // 内容偏移量 - 告诉滚动视图滚动了多少。 int pageNumber = floor((_scrollView.contentOffset.x - viewWidth/50) / viewWidth) +1;pageControl.currentPage=pageNumber; }。但问题出在 cellForItemAtIndexPath 中。它被调用了两次,所以得到的问题对象与屏幕上显示的对象不同。是因为滚动视图内容的大小或宽度吗?并创建了两个单元格???
  • 我认为你不能期望-[<UICollectionViewDataSource> collectionView:cellForItemAtIndexPath:] 以可预测的方式被调用。特别是如果有动画。设置currentQuestion 是个坏主意。最好在-[<UIScrollViewDelegate> scrollViewDidScroll:]中设置currentQuestion
  • 感谢 Mats,这运行良好并且确实解决了问题 :) 所以现在我在 scrollview 委托方法中设置 currentQuestion。但现在你建议如何在第 0 个索引上显示问题?因为 scrollviewDidScroll 只有在滚动到第一个索引单元格后才会被调用。因此它在第 0 个索引中显示为 null

标签: objective-c uicollectionview cell uicollectionviewcell


【解决方案1】:

我们现在应该预期会创建一些单元格 (cellForItemAtIndexPath:) 但从未在 iOS 10 中显示。 如果出于某种奇怪的原因我们不想要这种奇妙的新行为,我们可以将集合视图的 isPrefetchingEnabled 属性设置为 false(在 iOS 10 中默认为 true)。

希望这对某人有所帮助! :) 您可以参考以下链接[链接]UICollectionView cellForItem called not correctly

【讨论】:

  • 天啊,只有 1 行,我 this 在我得到这个答案之前几乎真的要做到if isiOS10。谢谢。
  • 拯救了这一天!感谢您的回答。
【解决方案2】:
 -(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;

}

试试这个,也许能解决你的问题。

【讨论】:

  • 感谢您的逻辑!但我的问题是 cellForItemAtIndexPath 被调用了两次,如果我添加此代码,则在滑动到第二个单元格时,cellforrowatindexpath 被称为索引路径 {length = 2, path = 0 - 1} 和 {length = 2, path = 0 - 2 } 即使不去第三个单元格。
  • 该问题仅在从第 0 个索引滚动到第 1 个索引时存在。当我在单元格上添加一个按钮时,它工作正常,单击该按钮会显示带有以下代码的下一个单元格。 -(void)nextButtonClicked:(UIButton*)nextButton{ pageControl.currentPage += 1; [self pageControlChanged:pageControl]; }
  • krissa 我认为您应该检查当前的滚动偏移量以了解是否必须加载调查 0。就像这个例子:if(scrollView.contentOffset.x
  • 没有让你好起来
猜你喜欢
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 2017-06-25
相关资源
最近更新 更多