NSSortDescriptor 在查看详细视图并返回后按字母顺序重新排序单元格

Posted

技术标签:

【中文标题】NSSortDescriptor 在查看详细视图并返回后按字母顺序重新排序单元格【英文标题】:NSSortDescriptor reorders cells alphabetically after viewing detail view and returning 【发布时间】:2014-05-04 18:54:28 【问题描述】:

我有一个或多或少基本的 Master Detail 应用程序。我已经关注 this tutorial 以熟悉 Core Data,现在我正在尝试在我的 Master TVC 上重新排列我的单元格。一切正常,包括成功重新排序我的单元格。然而,当我深入查看其中一个详细的 VC 时,我又回到了原始的按字母顺序排列的顺序。我相信这与教程中包含的NSSortDescriptorsortDescriptor”有关。我不确定如何删除它,或者如何赋予它不同的特性。任何帮助表示赞赏。下面是我的NSFetchedResultsController 方法。

-(NSFetchedResultsController*) fetchedResultsController 

    if (_fetchedResultsController != nil) 
        return _fetchedResultsController;
    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSManagedObjectContext *context = [self managedObjectContext];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Top" inManagedObjectContext:context];

    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"topName" ascending:YES];

    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    fetchRequest.sortDescriptors = sortDescriptors;

    _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];

    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

编辑: 经过过去几天的大量研究,我意识到这更多是我的 moveRowAtIndexPath 方法的问题。有人对使用 Core Data 和重新排序单元格的能力有任何建议或建议吗?另外,这是否需要自定义 tableviewcell 类?

【问题讨论】:

你的viewDidAppear方法做了什么?那里好像有什么东西被重置了。 @RainerSchwarze 我实际上并没有调用 viewDidAppear 方法。然而,我正在调用 viewWillAppear。这是代码:-(void) viewWillAppear:(BOOL)animated [self.tableView reloadData]; 重新排序是什么意思?如果您的意思是拖放单元格来决定它们的顺序,我想知道您是否正在保存在上下文中完成的更改。 @flexaddicted 我试图允许更改表格单元格出现顺序的功能。我不希望按字母顺序排列,可能更适合按照他们创建单元格的顺序排列它们。我希望用户能够决定哪个对他们最重要。类似于 canMoveRowAtIndexPath 和 moveRowAtIndexPath。 NSFetchedResultsController 不支持移动/重新排序 - 它是核心数据结果集的表示。要执行您似乎想做的事情,您必须在显示层维护一个集合,该集合由核心数据/获取的结果控制器填充,这就是您移动/重新排序的内容。这是可行的,但肯定会增加您的复杂性。 【参考方案1】:

您的表格视图是根据名称排序的。鉴于名称是固定的,如果您“手动”重新排序单元格然后返回表格视图,则重新建立基于名称的排序。

要获得所需的内容,您需要在 Core Data 模型中添加一个名为 sortIndex 的字段。然后,您使用基于sortIndexsortDescriptor 对表进行排序;您可以将sortIndex 初始化为创建顺序。当用户通过 UI 重新排序单元格时,您还将更改所有受影响的单元格/托管对象的 sortIndex。然后,由于sortIndex 是 Core Data 模型的一部分,当用户结束并重新启动您的应用程序时,他们的首选排序将被重新建立。

有时,出于建模原因,您不想在某个托管对象中直接包含sortIndex。例如,Person 有名字和姓氏,但没有sortIndex(实际上)。您可以创建一个关联,可能是一个DisplayPreferences 托管对象,在PersonDisplayPreferences 之间进行一对一映射,并且在DisplayPreferences 中拥有一个sortIndex

【讨论】:

这是对我来说真正有意义的第一件事,但是,我对这一切还很年轻,尤其是 Core Data。我已将“sortIndex”作为属性添加到我的 Core Data 的实体“Top”。我不熟悉初始化创建顺序,您能否再解释一下,例如使用哪种方法等。另外,我在哪里/如何在整个应用程序中更新 sortIndex 进行了更改。非常感谢! 在剖析了几个 github 项目之后,这些项目也符合您的描述,我得到了它的工作。非常感谢!真的很感激!【参考方案2】:

您需要在这里检查几件事:

    您需要通过在 NSFetchedResultsController 上调用 performFetch: 来实际执行第一次提取。要么在 getter 方法中执行此操作,要么应在 viewDidLoad 中执行此操作。 您是否正确实现了所需的 NSFetchedResultsControllerDelegate 方法?这包括controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:controller:didChangeSection:atIndex:forChangeType:controllerDidChangeContent:。代码都是样板,但您需要确保它在那里。

    你的 UITableViewDatasource 方法是什么样的?确保部分和行数如下所示:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    
        return [[[self fetchedResultsController] sections] count];
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    
        id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
        return [sectionInfo numberOfObjects];
      
    

    确保您使用 indexPath 在tableView:cellForRowAtIndexPath: 方法中抓取您的对象。它应该看起来像这样:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCellIdentifier"];
        NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
        cell.textLabel.text = rowPackage.title;
    
        return cell;
    
    

【讨论】:

感谢您的彻底回复,但我的代码中已说明了这些内容。我在很多地方读到这根本不应该在 FRC 中完成,而是在 moveRowAtIndexPath 中完成。不确定这是否有助于您更好地理解。再次感谢。

以上是关于NSSortDescriptor 在查看详细视图并返回后按字母顺序重新排序单元格的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSSortDescriptor 按时间错误排序(带有核心数据)

Firebase 分析 - 如何在事件详细信息视图中查看所有用户属性

NSSortDescriptor 可以使用部分键进行排序吗?

使用两个 NSSortDescriptor 过滤数组

mysql中的视图

下载pdf后重定向查看