旋转时多次调用方法 collectionview(cellForItemAtIndexPath)

Posted

技术标签:

【中文标题】旋转时多次调用方法 collectionview(cellForItemAtIndexPath)【英文标题】:Method collectionview(cellForItemAtIndexPath) is called many times when i rotate 【发布时间】:2016-06-10 05:38:42 【问题描述】:

我正在学习 Swift。我有 2 个问题。 完整来源是here。

1. 为什么这样多次调用 collectionview(cellForItemAtIndexPath)?编辑:我想知道的是为什么每次轮换事件都会多次调用 collectionview(cellForItemAtIndexPath)。

1) 旋转方式

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) 

    print("4 self.collectionView.frame=\(self.collectionView.frame)")
    print("4 size=\(size)")

    self.collectionView.frame.size = size

    let currentSize = self.collectionView.bounds.size
    let offset = CGFloat(self.indexPathRow) * size.height
    print("offset=\(offset)")
    self.collectionView.setContentOffset(CGPointMake(0, offset), animated: true)
    print("self.collectionView.contentOffset=\(self.collectionView.contentOffset)")

    // Suppress the layout errors by invalidating the layout
    self.collectionView.collectionViewLayout.invalidateLayout();


    // Where is the best location of super? Top of this method or bottom?
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

2) 集合视图方法

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 

    currentOffset = self.collectionView.contentOffset
    print("currentOffset=\(currentOffset)")

    //print("indexPath=\(indexPath.row)")
    let frame = self.collectionView.frame

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseCellIdentifier, forIndexPath: indexPath) as! MainCollectionViewCell

    let imageName = dataArray[indexPath.row]
    let image = UIImage(named: imageName)
    cell.imageView.image = image
    if (frame.size.width >= frame.size.height) 
        cell.imageView.frame = frame
    
    else 
        cell.imageView.frame = CGRectMake(0, 0, frame.width*2, frame.height)
    
    print("cell.imageView.frame=\(frame)")
    print("cell.imageView.image=\(cell.imageView.image!.size)")

    if (indexPath.row % 2 == 0) 
        cell.backgroundColor = UIColor.orangeColor()
    
    else 
        cell.backgroundColor = UIColor.yellowColor()
    

    currentIndex = Int(currentOffset.y / frame.size.height)
    print("currentIndex=\(currentIndex)")
    indexPathRow = indexPath.row

    return cell

    我从横向旋转到纵向时遇到警告消息。我不想看到这个警告,但我不能。以下是我旋转时的日志消息。此消息显示多个调用方法。 (您可以遇到此日志 - 横向传递第 12 个单元格,然后旋转到纵向。)
 4 self.collectionView.frame=(0.0, 0.0, 667.0, 375.0)
    4 大小=(375.0, 667.0)
    2016-06-10 14:22:05.750 CollectionViewWithoutStoryboard[49615:2682527] UICollectionViewFlowLayout 的行为未定义,因为:
    2016-06-10 14:22:05.750 CollectionViewWithoutStoryboard[49615:2682527] 项目宽度必须小于 UICollectionView 的宽度减去部分插入左右值,减去内容插入左右值。
    2016-06-10 14:22:05.751 CollectionViewWithoutStoryboard[49615:2682527] 相关的 UICollectionViewFlowLayout 实例是,它附加到;层 = ;内容偏移:0, 4875; contentSize: 667, 7500> 集合视图布局:.
    2016-06-10 14:22:05.751 CollectionViewWithoutStoryboard[49615:2682527] 在 UICollectionViewFlowLayoutBreakForInvalidSizes 处创建一个符号断点以在调试器中捕获此问题。
    偏移量=8671.0
    self.collectionView.contentOffset=(0.0, 4729.0)
    self.collectionView.frame=(0.0, 0.0, 375.0, 667.0)
    currentOffset=(0.0, 4729.0)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    当前索引=7
    currentOffset=(0.0, 4729.0)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    当前索引=7
    self.collectionView.frame=(0.0, 0.0, 375.0, 667.0)
    currentOffset=(0.0, 5449.0)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    当前索引=8
    currentOffset=(0.0, 6029.5)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    当前索引=9
    currentOffset=(0.0, 6717.0)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    当前索引=10
    currentOffset=(0.0, 7393.0)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    当前索引=11
    currentOffset=(0.0, 8218.5)
    cell.imageView.frame=(0.0, 0.0, 375.0, 667.0)
    cell.imageView.image=(1920.0, 804.0)
    currentIndex=12

【问题讨论】:

【参考方案1】:

看看这个问题

Answer detailing how cellForRowAtIndexPath works

上面的答案详细说明了cellForRowAtIndexPathUITableView 中的工作原理

UICollectionView 中的cellForItemAtIndexPath 是围绕相同的概念构建的。您可以将这两个控件视为UIScrollView 的优化版本。由于 TableView 或 CollectionView 可能包含多个项目,因此控件会重用视图,并且在绘制该特定单元格时调用此方法。 因此,不要将这些方法视为初始化程序,而应将其视为需要指定单元格外观的绘图方法。

我希望这个解释有帮助!

【讨论】:

感谢您的回答。但我想知道的是为什么 collectionview(cellForItemAtIndexPath) 每次旋转事件都会被调用多次。 在一个旋转事件中调用不同的单元格。在用户滚动之前,ios 会出列并为用户准备好 2-3 个单元格。 PS:如果对你有帮助,请点赞并采纳 我能理解。我想投票,但我的声誉还不够。 谢谢!当你有代表的时候再做吧:)

以上是关于旋转时多次调用方法 collectionview(cellForItemAtIndexPath)的主要内容,如果未能解决你的问题,请参考以下文章

CollectionView旋转水平卡片布局

shouldAutorotateToInterfaceOrientation 连续调用多次,没有任何旋转

如何多次围绕锚点旋转视图

CollectionView 和旋转问题

按照用户方向旋转collectionView

旋转屏幕时,带有嵌入式 tableview 的 Collectionview 被剪裁