单元格加载到 cellForItemAt 中,但未加载到 visibleCells 中
Cell loaded in cellForItemAt, but not in visibleCells
我有一个自定义 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 { [=10=] as? CustomCell }
panningIsActive = active
UIView.animate(duration: 0.3) {
cells.forEach { [=10=].label.alpha = [=10=].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
}
我该怎么做才能更改所有 "loaded" 个单元格,而不仅仅是 "visible" 个单元格?
听起来你可能想尝试使用 layoutAttributesForElements(in:)
。
您需要实现自己的集合视图布局子类(而不是使用委托方法),但我认为从长远来看这是值得的。
您无需手动管理动画(通过 UIView.animateWithDuration
),而是使用此方法告诉集合视图单元格在不同位置应具有哪些属性,并且当人们平移集合视图时,正确的属性会自动应用。
我试图为此找到一个很好的 Swift 参考,但我找不到,但是如果你想尝试这个,可以按照 Objective-C 中的 post方法:
https://bradbambara.wordpress.com/2014/05/24/getting-started-with-custom-uicollectionview-layouts/
visibleCells 只是屏幕上的单元格。这曾经是在 cellForItem:at 中初始化的所有内容:但是从 iOS 10 开始,UICollectionView 现在预取以提高滚动性能(see WWD 2016 video) which maybe why you are having this problem. Anyways it sounds like all you want to do is animate the cells to fade in when they come on screen. You can either move your animation logic to willDisplayCell or subclass UICollectionViewCell. UIColectionViewCell inherits from UIView, so you can override didMoveToSuperView 在你的 UICollectionViewCell 中并在那里调用你的动画方法,这将导致单元格显示动画。
我正在使用 Xcode 11.4 和 Swift 5,我遇到了完全相同的问题:.visibleCells
没有给我所有的 已加载 个细胞。
通过阅读 @Josh Homann 的回答和下面的评论,我找到了 2 个解决方案。
第一个解决方案与您在以下位置找到的解决方案相同:在 collectionView(_:willDisplay:_:)
中加载后但在屏幕上显示之前自定义单元格外观。
另一个快速而肮脏的解决方案是在属性检查器中简单地取消选中 UICollectionView 的“Prefetch”选项。
这解决了这个问题,因为通过禁用预取,UICollectionView 将停止预加载未显示在屏幕上的单元格,因此 .visibleCells
现在是所有已加载的单元格。如果您只是在单元格中加载静态或小型本地数据,则此解决方案会很好地工作。如果您要从网络为即将到来的单元预取大数据(例如图像),您可能需要启用预取,那么解决方案 1 是您的首选。
我有一个自定义 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 { [=10=] as? CustomCell }
panningIsActive = active
UIView.animate(duration: 0.3) {
cells.forEach { [=10=].label.alpha = [=10=].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
}
我该怎么做才能更改所有 "loaded" 个单元格,而不仅仅是 "visible" 个单元格?
听起来你可能想尝试使用 layoutAttributesForElements(in:)
。
您需要实现自己的集合视图布局子类(而不是使用委托方法),但我认为从长远来看这是值得的。
您无需手动管理动画(通过 UIView.animateWithDuration
),而是使用此方法告诉集合视图单元格在不同位置应具有哪些属性,并且当人们平移集合视图时,正确的属性会自动应用。
我试图为此找到一个很好的 Swift 参考,但我找不到,但是如果你想尝试这个,可以按照 Objective-C 中的 post方法: https://bradbambara.wordpress.com/2014/05/24/getting-started-with-custom-uicollectionview-layouts/
visibleCells 只是屏幕上的单元格。这曾经是在 cellForItem:at 中初始化的所有内容:但是从 iOS 10 开始,UICollectionView 现在预取以提高滚动性能(see WWD 2016 video) which maybe why you are having this problem. Anyways it sounds like all you want to do is animate the cells to fade in when they come on screen. You can either move your animation logic to willDisplayCell or subclass UICollectionViewCell. UIColectionViewCell inherits from UIView, so you can override didMoveToSuperView 在你的 UICollectionViewCell 中并在那里调用你的动画方法,这将导致单元格显示动画。
我正在使用 Xcode 11.4 和 Swift 5,我遇到了完全相同的问题:.visibleCells
没有给我所有的 已加载 个细胞。
通过阅读 @Josh Homann 的回答和下面的评论,我找到了 2 个解决方案。
第一个解决方案与您在以下位置找到的解决方案相同:在 collectionView(_:willDisplay:_:)
中加载后但在屏幕上显示之前自定义单元格外观。
另一个快速而肮脏的解决方案是在属性检查器中简单地取消选中 UICollectionView 的“Prefetch”选项。
这解决了这个问题,因为通过禁用预取,UICollectionView 将停止预加载未显示在屏幕上的单元格,因此 .visibleCells
现在是所有已加载的单元格。如果您只是在单元格中加载静态或小型本地数据,则此解决方案会很好地工作。如果您要从网络为即将到来的单元预取大数据(例如图像),您可能需要启用预取,那么解决方案 1 是您的首选。