NSFetchedResultsController - 如何在 cellForRowAtIndexPath 中显示正确的部分行
Posted
技术标签:
【中文标题】NSFetchedResultsController - 如何在 cellForRowAtIndexPath 中显示正确的部分行【英文标题】:NSFetchedResultsController - How to show the right sections rows in cellForRowAtIndexPath 【发布时间】:2013-09-05 10:29:22 【问题描述】:我有一个 JSON 读取的国家和地点列表。它现在可以正确读取并似乎存储了关系。
// Read JSON
NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"venues" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:jsonPath];
id json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error)
NSLog(@"Error - %@", error);
else
//NSLog(@"JSON = %@", json);
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^
/*
"USA": [
"venue": "Von Braun Center",
"city" : "Huntsville",
"state": "Alabama",
"capacity": 13760
,
*/
for (NSDictionary *dict in json)
NSString *name = (NSString *) [dict objectForKey:@"name"];
NSArray *venueList = (NSArray *) [dict valueForKey:@"venues"];
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *c)
Country *country = [Country createInContext:c];
[country setName:name];
NSMutableArray *listOfVenues = [NSMutableArray array];
NSLog(@"Country - %@", country.name);
for (NSDictionary *venueData in venueList)
NSString *name = (NSString *) [venueData objectForKey:@"venue"];
NSString *city = (NSString *) [venueData objectForKey:@"city"];
NSString *state = (NSString *) [venueData objectForKey:@"state"];
//NSNumber *capacity = (NSNumber *) [NSNumber numberWithInt:[[venueData valueForKey:@"capacity"] intValue]];
Venue *v = [Venue createInContext:c];
[v setName:name];
[v setCity:city];
[v setState:state];
[v setCountry:country];
[listOfVenues addObject:v];
NSLog(@"Venue - %@, %@", v.name, v.country.name);
// next
[country setVenues:[NSSet setWithArray:listOfVenues]];
completion:^
];
// next
dispatch_async(dispatch_get_main_queue(), ^
[[NSManagedObjectContext defaultContext] saveNestedContexts];
NSUInteger entities = [Venue countOfEntities];
NSLog(@"Venues saved = %d", entities);
);
);
// end if
这会产生一个场地日志,像这样;
正在加载场地数据...
Country - USA
Venue - Von Braun Center, USA
Venue - Birmingham Convention Center, USA
Country - UK
Venue - O2 Arena, UK
Venue - MEN Arena, UK
到目前为止一切顺利。
但是当我进入实际的场地视图时,它只是按字母顺序显示场地,但它确实显示了正确的部分
我的代码是;
// viewDidLoad
self.fetchedResultsController = [Venue fetchAllGroupedBy:@"country.name" withPredicate:nil sortedBy:@"name" ascending:YES];
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return [[self.fetchedResultsController sections] count];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo name];
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[self configureCell:cell atIndexPath:indexPath];
return cell;
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
Venue *v = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = v.name;
这会在屏幕上产生以下内容;
我已尝试重置应用程序及其数据,但无济于事。
截图 (via Imageshack)
如您所见,该列表仅按字母顺序排列,不正确,也未拆分到相关部分。
似乎源于
Venue *v = [self.fetchedResultsController objectAtIndexPath:indexPath];
线,但我不知道如何修复它。
我想知道我做错了什么以及如何修复它,以便它在正确的部分显示正确的数据。
【问题讨论】:
您的屏幕截图在我看来还可以。您可以按国家/地区名称分组,并在一个部分中按场地名称排序。有什么问题? 场地不在正确的国家。 IE:美国航空竞技场在英国不存在,应该列在 USA not UK 下。 记录未显示在正确的组中 【参考方案1】:在设置国家/地区后
[v setCountry:country];
这条线是多余的,可能会破坏你们的关系
[country setVenues:[NSSet setWithArray:listOfVenues]];
您只需设置一次关系。反向关系是自动生成的。
【讨论】:
哦,好吧,我试试这个 我现在已经解决了这个问题,我可以对场地进行分组;但场地尚未订购 太棒了——成功了!!你应该接受答案。至于订购,您可以通过sortedArrayUsingSortDescriptors:
检索物品后订购。
我会试一试
这很奇怪,因为我希望Venue fetchAllGroupedBy:@"country.name" withPredicate:nil sortedBy:@"name" ascending:YES
按国家名称分组并按场地名称排序;但看起来它并没有这样做;我会尝试排序描述符【参考方案2】:
我能够将这些部分放在正确的组中(即:美国场馆现在属于美国国家/地区)
self.fetchedResultsController = [Venue fetchAllGroupedBy:@"country.name" withPredicate:nil sortedBy:@"country.name" ascending:YES delegate:self inContext:managedObjectContext];
但是现在发生的事情是场地没有按名称升序排列。
我得到一个这样的列表;
截图: http://img443.imageshack.us/img443/340/6f3o.png
场地现在按国家/地区分组,但场地本身并未按 A-Z 排序。
我希望我的场地安排在 A-Z 并且国家/地区不会被排序。
但我不知道该怎么做。
【讨论】:
以上是关于NSFetchedResultsController - 如何在 cellForRowAtIndexPath 中显示正确的部分行的主要内容,如果未能解决你的问题,请参考以下文章