如何重新绘制不可见的UICollectionViewCell的旋转后准备好重用时发生?

如何重绘不可见的UICollectionViewCell准备好时重用发生?

我想到的一种方法是在Layout Cell prepareForReuse函数中使用代码,但是它的工作原理是非最优的,因为它会导致需要更多的重绘。

背景:在当前不可见的方向改变之后,需要为单元格触发drawRect ,但是popup来使用并且没有被重画,所以到目前为止,我只能看到prepareForReuse是合适的。 问题是我正在重新绘制所有的“重用”单元格,而我真的只想重绘那些最初popup在设备的前一个方向位置创build的单元格。

其他信息:所以目前我正在这样做:

在ViewController中:

 override func viewWillLayoutSubviews() { // Clear cached layout attributes (to ensure new positions are calculated) (self.cal.collectionViewLayout as! GCCalendarLayout).resetCache() self.cal.collectionViewLayout.invalidateLayout() // Trigger cells to redraw themselves (to get new widths etc) for cell in self.cal?.visibleCells() as! [GCCalendarCell] { cell.setNeedsDisplay() } // Not sure how to "setNeedsDisplay" on non visible cells here? } 

在布局单元格类中:

 override func prepareForReuse() { super.prepareForReuse() // Ensure "drawRect" is called (only way I could see to handle change in orientation self.setNeedsDisplay() // ISSUE: It does this also for subsequent "prepareForReuse" after all // non-visible cells have been re-used and re-drawn, so really // not optimal } 

没有在上面的prepareForReuse中的代码发生的例子。 方向改变之后拍摄的快照,以及稍微向上滚动之后:

在这里输入图像说明

我想我现在在这里:

 import UIKit @IBDesignable class GCCalendarCell: UICollectionViewCell { var prevBounds : CGRect? override func layoutSubviews() { if let prevBounds = prevBounds { if !( (prevBounds.width == bounds.width) && (prevBounds.height == bounds.height) ) { self.setNeedsDisplay() } } } override func drawRect(rect: CGRect) { // Do Stuff self.prevBounds = self.bounds } } 

注意到这个检查在“prepareForReuse”中不起作用,因为此时单元没有应用旋转。 似乎工作在“layoutSubviews”,但是。

您可以在单元格和持有集合视图的视图控制器(协议和委托或传递块甚至直接引用VC)之间实现某种通信。 然后您可以要求视图控制器进行轮换更改。

它有点混乱,但如果你有你的视图控制器中的某种旋转跟踪你可以用一个简单的if语句过滤setNeedsDisplay。

我有类似的挑战,更新已经显示和closures屏幕的单元格。 虽然通过ALLL细胞循环可能不可能 – 刷新/循环不可见的是。 如果这是你的用例 – 然后阅读。 预警 – 如果你添加这样的代码 – 解释你为什么这样做。 这是一种反模式 – 但可以帮助修复该错误,并帮助发送您的应用程序,尽pipe增加了不必要的复杂性。 不要在应用程序的多个地方使用这个。

任何被取消初始化的collectionviewcell(离开屏幕并被重新扫描)都应该自动取消订阅。

通知模式

 let kUpdateButtonBarCell = NSNotification.Name("kUpdateButtonBarCell") class Notificator { static func fireNotification(notificationName: NSNotification.Name) { NotificationCenter.default.post(name: notificationName, object: nil) } } extension UICollectionViewCell{ func listenForBackgroundChanges(){ NotificationCenter.default.removeObserver(self, name: kUpdateButtonBarCell, object: nil) NotificationCenter.default.addObserver(forName:kUpdateButtonBarCell, object: nil, queue: OperationQueue.main, using: { (note) in print( " contentView: ",self.contentView) }) } } override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("die", forIndexPath: indexPath) as UICollectionViewCell cell.listenForBackgroundChanges() return cell } // Where appropriate broadcast notification to hook into all cells past and present Notificator.fireNotification(notificationName: kUpdateButtonBarCell) 

委托模式

有可能简化这个….给读者一个练习。 只是不要保留单元格(使用薄弱环节) – 否则你会有内存泄漏。