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 时,我又回到了原始的按字母顺序排列的顺序。我相信这与教程中包含的NSSortDescriptor
“sortDescriptor
”有关。我不确定如何删除它,或者如何赋予它不同的特性。任何帮助表示赞赏。下面是我的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
的字段。然后,您使用基于sortIndex
的sortDescriptor
对表进行排序;您可以将sortIndex
初始化为创建顺序。当用户通过 UI 重新排序单元格时,您还将更改所有受影响的单元格/托管对象的 sortIndex
。然后,由于sortIndex
是 Core Data 模型的一部分,当用户结束并重新启动您的应用程序时,他们的首选排序将被重新建立。
有时,出于建模原因,您不想在某个托管对象中直接包含sortIndex
。例如,Person
有名字和姓氏,但没有sortIndex
(实际上)。您可以创建一个关联,可能是一个DisplayPreferences
托管对象,在Person
和DisplayPreferences
之间进行一对一映射,并且在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 分析 - 如何在事件详细信息视图中查看所有用户属性