在 UITableView 中重新排序 Realm 对象



>我有一个RLMObject模型对象的集合,表示用户的登录帐户可以在"我的应用"中进行管理。这些对象通过直接映射到UITableView来公开在应用程序中。

由于用户可以通过以下方式显式控制这些帐户对象的顺序表视图,模型对象具有一个名为 orderedIndex 的属性,按顺序排列以跟踪对象的当前顺序。

@interface Account : RLMObject
@property NSString *name;
@property NSInteger orderedIndex;
@end

表视图数据源从RLMResults属性访问这些帐号父视图控制器的成员

self.accounts = [[Account allObjects] sortedResultsUsingProperty:@"orderedIndex" ascending:YES];

(由于 Realm 对象是"实时"的,我永远不必手动重新加载或重置此对象。

当用户对表视图的行重新排序时,所有 的 orderedIndex 属性的这些 Realm 对象需要更新以匹配。

可能有很多不同的方法可以做到这一点,有些比其他方法更复杂,但是什么是最简单的呢?

最初,我试图在确定哪些特定的 Realm 对象时对此保持聪明。受到移动的影响,只修改了他们的orderedIndex值,但这变成了有些复杂,在某些边缘情况下(通常涉及顶部和底部的对象),将导致不可预测的行为。

最终

,我决定为了最终的简单性(以牺牲更多的工作为代价),我会只需将我的 self.accounts 对象的内容复制到可变数组中,执行数组中的移动操作,然后简单地重建每个对象的orderedIndex从零开始。

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(nonnull NSIndexPath *)sourceIndexPath toIndexPath:(nonnull NSIndexPath *)destinationIndexPath
{   
   if (sourceIndexPath.row == destinationIndexPath.row) {
       return;
   }
   // Make a mutable copy of the accounts list
   NSMutableArray *array = [NSMutableArray array];
   for (Account *account in self.accounts) {
       [array addObject:account];
   }
   // Re-order this array as dictated by the table view
   Account *accountToMove = array[sourceIndexPath.row];
   [array removeObject:accountToMove];
   [array insertObject:accountToMove atIndex:destinationIndexPath.row];
   // Loop through all of the items and reset their index value
   [self.accounts.realm transactionWithBlock:^{
       NSInteger i = 0;
       for (Account *account in array) {
           account.orderedIndex = i++;
       }
   }];
}

这最终完美地工作了。 :)

解决此问题的另一种方法是使用 Realm 中的 List 数据结构。因此,您可以拥有一个 Realm 对象列表,并且对列表中的元素进行重新排序与对常规数组进行重新排序的方式完全相同。如果有兴趣,您可以查看以下链接,了解 Swift 是如何完成此操作的。:-)

在 UITableViewController 中重新排序行后 UI 更新不正确

最新更新