使用 NSPredicate 过滤后更新 UItableView 及其数据源的模式

Posted

技术标签:

【中文标题】使用 NSPredicate 过滤后更新 UItableView 及其数据源的模式【英文标题】:Pattern to update a UItableView and its datasource after filtering with NSPredicate 【发布时间】:2009-06-16 01:13:37 【问题描述】:

这似乎应该是直截了当的。从技术上讲,我可以完成这项工作,但如果我想执行某些 UI 动画(使用 deleteRowsAtIndexPaths:withRowAnimation:),事情就会变得棘手。似乎数据源和 UI 正在争论谁应该先删除。然后我必须人为地保留数据以进行 UI 更新。

我目前的设置:

在我的模型中:

    创建一个多维 NSArray 以 保存我的数据。 (每个子数组 代表一个部分)。 在每个部分中放置一个 NSDictionary 数组来表示一个数据 单个单元格。

在我的视图控制器中:

    创建一个多维 NSArray 以 握住我的单元控制器(模仿 数据结构)。 将每个模型字典分配给 ivar 在适当的单元格中 控制器。 将数据连接到单元格

这会让我的 UITableView 在屏幕上正确显示单元格。现在,如果我想过滤表中的数据,请执行以下操作:

在我的模型中:

    创建一个 NSPredicate 实例。 过滤每个子数组 多维数组。 在每个字典中设置一个标志 是在结果的范围内 过滤后的数组。

在我的视图控制器中:

    我创建了一个新的多维 NSArray。该数组将保存 “过滤”的单元控制器 数据” 循环通过电流 多维控制器数组。 将其添加到新的“过滤数组如果 它的模型标志已设置。 更换未过滤的控制器 与新的数组。 更新表格。

这也很有效。只要我不介意 UI 即时更新。如果我想删除带有动画的行,我必须将这些索引传递给要删除的表。

为此,我向视图控制器添加了几个步骤:

在我的视图控制器中:

    我创建了一个新的多维 NSArray。该数组将保存 “过滤”的单元控制器 数据” 循环通过电流 多维控制器数组。 将其添加到新的“过滤数组如果 它的模型标志已设置。 创建一个新的 NSArray 来保存索引 被删除。 循环通过电流 多维控制器数组。 将其单元格的索引添加到 "toBeDeleted" 数组,如果它的模型是 未设置标志。 更换未过滤的控制器 与新的数组。 执行 deleteRowsAtIndexPaths:withRowAnimationn。

到目前为止,这种方法效果不佳。我在删除带有边缘情况的行时遇到问题(空白部分和所有可见单元格都被删除)。

这让我觉得我的方法可能有缺陷。有没有人在应用程序中实现过这个?你是怎么解决这个问题的?你的行动画有效吗?

【问题讨论】:

我已经使用我概述的here(个人博客文章)的设计实现了这一点,当我清理它并使其更通用时,我将发布一些特定的代码。 【参考方案1】:

不要让事情变得更糟,但是您是否在实际设备上尝试过 NSPredicate?

我发现 NSPredicate 在模拟器上工作,但很像 NSXMLDocument,在设备本身 (2.2.1) 上不可用。


更新:鉴于 NSPredicate 可用,我可以补充的是,我使用 deleteRowsAtIndexPaths:withRowAnimation 也得到了不可预测的结果 - 我不得不接受调用 reloadData 并进行非动画转换。

幸运的是,由于我的应用中有一个高度“减法”过滤器,因此通常会有很多动作,因此用户很明显发生了某些事情。

在您的可见更改可能不明显的情况下,我怀疑从可用性的角度来看,只需使用动画 UIImageView 从北向南移动穿过 UITableView 区域就足够了。 (不幸的是,这本身就是一个挑战)。

即使没有发生可见的变化,这也会有额外的好处,即向用户确认过滤器的应用程序。

【讨论】:

这在 2.2.1 上不可用,你是对的。但在 [redacted] 上可用。

以上是关于使用 NSPredicate 过滤后更新 UItableView 及其数据源的模式的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate 与具有多个对象的 Array 一起使用

NSPredicate 按数组中包含的第一个字母过滤

使用 nspredicate 进行字典过滤

使用 NSPredicate 过滤 EKEvent

NSPredicate的使用

使用 NSPredicate 过滤文件路径