单元格加载在cellForItemAt中,但不在visibleCells中

时间:2017-01-04 01:29:25

标签: swift uicollectionview uicollectionviewcell

我有一个自定义UICollectionView并且单元格已加载到cellForItemAt中,但是当我尝试使用visibleCells获取所有可见单元格时,我没有获得所有单元格。

例如,在cellForItemAt中,我将单元格中标签的alpha设置为0。平移时,我希望这些标签的alpha值更改为1

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    handleLabel(scrollView, active: true)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    if pickerIsActive { handleLabel(scrollView, active: false) }
}

private func handleLabel(_ scrollView: UIScrollView, active: Bool) {
    guard let pickerView = scrollView as? UICollectionView else { return }

    let cells = pickerView.visibleCells.flatMap { $0 as? CustomCell }

    panningIsActive = active

    UIView.animate(duration: 0.3) {
        cells.forEach { $0.label.alpha = $0.isSelected || active ? 1 : 0 }
    }
}

和cellForItemAt:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell

    cell.label.alpha = 0

    return cell
}

如何更改所有已加载的"细胞而不仅仅是'#34;可见"细胞

3 个答案:

答案 0 :(得分:2)

我正在使用Xcode 11.4和Swift 5,但我遇到了完全相同的问题:.visibleCells并没有给我所有 已加载 单元格。 / p>

通过阅读 @Josh Homann 的答案和下面的评论,我找到了两种解决方案。

第一个解决方案与您达到的解决方案相同:在collectionView(_:willDisplay:_:)中自定义单元格外观,在加载后但在屏幕上显示之前。

另一种快速又肮脏的解决方案是,只需在属性检查器中取消选中UICollectionView的“ 预取”选项。

此问题得以解决,因为通过禁用预取,UICollectionView将停止预加载屏幕上未显示的单元格,因此.visibleCells现在是所有已加载的单元格。如果您只是在单元格中加载静态或小型本地数据,则此解决方案会很好用。如果您要为即将到来的单元从网络中预取大数据(例如图像),则可能需要启用“预取”,那么解决方案1是您的首选。

uncheck Prefetch checkbox

答案 1 :(得分:1)

听起来您可能想尝试使用layoutAttributesForElements(in:)

您需要实现自己的集合视图布局子类(而不是使用委托方法),但我认为从长远来看它是值得的。

不是手动管理动画(通过UIView.animateWithDuration),而是使用此方法告诉集合视图单元格在不同位置应具有哪些属性,并且当人们平移集合视图时,将自动应用正确的属性。

我试图为此找到一个好的Swift参考,但我不能,但是如果您想尝试这种方法,可以使用Objective-C中的帖子: https://bradbambara.wordpress.com/2014/05/24/getting-started-with-custom-uicollectionview-layouts/

答案 2 :(得分:1)

visibleCells只是屏幕上的细胞。这曾经是在cellForItem中初始化的所有内容:at:但是从iOS 10开始,UICollectionView现在预取以提高滚动性能(see WWD 2016 video),这可能就是为什么你遇到这个问题。无论如何,听起来你想要做的就是让细胞在屏幕上显示时淡入淡出。您可以将动画逻辑移动到willDisplayCell或子类UICollectionViewCell。 UIColectionViewCell继承自UIView,因此您可以覆盖UICollectionViewCell中的didMoveToSuperView并在那里调用您的动画方法,这将使单元格在显示时进行动画处理。