如何实现显示“有状态”内容的 UICollectionViewCells?

Posted

技术标签:

【中文标题】如何实现显示“有状态”内容的 UICollectionViewCells?【英文标题】:How to implement UICollectionViewCells showing "stateful" contents? 【发布时间】:2013-02-28 13:38:33 【问题描述】:

我目前正在重构我的报亭应用。

之前,我展示了几个自定义的UIViews(“CoverView”),嵌入在滚动视图中的自计算网格布局(每行 3 个项目,行数根据需要)中,垂直滚动。

每个“CoverView”由

标签(显示问题标题) 图片(显示问题封面) 一个按钮(显示“下载”或 - 如果已下载 - “阅读”) 进度条(最初隐藏,显示下载进度)

每个 CoverView 都有自己的 UITapGestureRecognizerUILongPressGestureRecognizer

如果用户点击一次,按钮会被隐藏,下载进度条会显示并随着下载进度不断更新:

 [issue addObserver:cover forKeyPath:@"downloadProgress" options:NSKeyValueObservingOptionNew context:NULL]; 

(长按识别器用于让用户删除问题)。

所有 CoverView 都存储在 NSMutableDictionary 中,并且始终保存在内存中。尽管未缩放的图像相当大(1024 像素高),但我在滚动时从未遇到过性能问题,可能是因为存储的问题(以及 CoverView)并不多。

由于自行实现的网格布局复杂且难以维护,我想改用UICollectionView。我添加了一个集合视图并使我的 CoverView 类继承自 UICollectionViewCell(而不是 UIView)。

显示和滚动正常,但我遇到了这些问题:

    当需要显示新的一行单元格并且为每个单元格调用 collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 时,滚动会滞后。

    我尝试不重用单元(以提高性能,很奇怪),但这失败了,因为每个单元都必须设置它的 重用标识符(并且“reuseIdentifier”属性是只读的,所以我不能在代码中设置它)。

    我不知道在哪里为单元格的 KVO 取消设置观察者。有没有办法在单元格排队等待重用时收到通知?

总的来说,我不确定我是否在此处的特定用例中误用了UICollectionView,应该坚持我以前的方法,还是只是我无法有效地使用和调整UICollectionView

【问题讨论】:

希望这段代码对你有帮助:github.com/lequysang/TestCollectionViewWithProgressBar Sang,谢谢 - 下载实际上是在“问题”类中处理的(它充当模型并且没有 GUI 元素或依赖项)。 【参考方案1】:

要设置'reuseIdentifier',正确的设计是使用 UICollectionView 方法:

registerClass:forCellWithReuseIdentifier:registerNib:forCellWithReuseIdentifier:

您通常调用这些方法一次,具体取决于您希望如何提供单元的实例化(从 NIB 膨胀,或通过标准 [[ViewClass alloc] init] 实例化)

一旦注册了视图,您就可以像这样从 UiCollectionView 使用它们:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"yourReuseId" forIndexPath:indexPath];
    // Collection view handle ALL the work :
    // 1 - retrieves a reusable view if views have already been recycled
    // or 2- instantiate a new one, using the class/nib you registered
    // So, cell SHOULDN'T be nil from here :)


    // Note : from ios 6, UITableView has a similar auto-instantiation mechanism


3 - 要取消设置 KVO,覆盖 UICollectionViewCell-(void)prepareForReuse 方法(继承自 UICollectionReusableView

【讨论】:

以上是关于如何实现显示“有状态”内容的 UICollectionViewCells?的主要内容,如果未能解决你的问题,请参考以下文章

自定义UICollectinviewFlowLayout,即实现瀑布流

STreamlit 如何实现在每次小部件交互后不会重新运行的有状态 ML 应用程序

根据内容居中水平 UICollectionView

如何使用JS实现页面内容随机显示

Flutter - setState 不更新内部有状态小部件

JQuery如何实现点击查看更多,显示更多内容