手动计算UITableView部分

时间:2012-10-11 05:33:48

标签: objective-c uitableview nsfetchedresultscontroller

在Apple Development论坛上有一个关于手动为大行集计算表视图部分的有趣讨论。要查看它,需要开发者帐户:

NSFetchedResultsController fetching all objects in the DB...

要为没有开发帐户的人重新启用,Apple技术人员建议使用包含索引标题的实体,该实体与要在行中显示的实体有多对多的关系。

典型的例子是歌曲或艺术家的集合,其中索引部分标题是第一个字母A,B,C ......

因此,标题为A的实体与以字母A开头的歌曲之间存在多对多的关系,依此类推。

该机制是使用获取的结果控制器来检索所有歌曲,同时启动获取请求以检索NSArray索引。

NSFetchRequest *req = //fetch request for section entity
NSArray *sections = [MOC executeFetchRequest:req error:&error];

在部分中获取节数和行非常容易:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    NSInteger abc = [self.sections count];
    return abc;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    CardSection *s = (CardSection*)[self.sections objectAtIndex:section];
    NSInteger rows = [s.cards count];
    return rows;
}

-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    CardSection *s = [self.sections objectAtIndex:section];
    NSString *title = s.title;
    return title;
}

但是,问题从索引路径中的行的单元格开始:

- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSManagedObject obj = [_fetchedResultsController objectAtIndexPath:indexPath];
    // build cell....    
    return cell;
}

因为索引路径显然是指计算的部分和行,因此获取的控制器超出范围。

当然这可以通过调用section实体并在NSSet关系中请求一个特定的索引对象来解决,但这样就失去了获取控制器的好处。

我想知道是否有人尝试过这种方法,他是如何设法解决这个问题的。

1 个答案:

答案 0 :(得分:0)

到目前为止我找到的唯一解决方案是发布解析sections数组以查找特定索引处的前一个对象的数量。

        int latestCount=0;
        // BOX_INT is just a personal macro for converting something to NSNumber
        self.totalAtIndex=[NSMutableDictionary dictionaryWithCapacity:0];
        [self.totalAtIndex setObject:BOX_INT(0) forKey:BOX_INT(0)];
        for (int i=1;i<[self.sections count];i++) {
            CardSection *cardSection = [self.sections objectAtIndex:i-1];
            latestCount = latestCount + [cardSection.cards count];
            [self.totalAtIndex setObject:BOX_INT(latestCount) forKey:BOX_INT(i)];
        }

例如,假设这是我的部分,其中[a,b]只是NSIndexPath:

[0,0][0,1] (2 objects)
[1,0]      (1 object)
[2,0][2,1] (2 object)

如果我在索引2处, [self.totalAtIndex objectAtIndex:2] 将包含在索引0 +索引1之前存储的对象数量,因此返回3。 索引[2,1]转换为[0,5]。

这是对应的cellForRow:atIndexPath:

- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // hack index path
    NSInteger section = indexPath.section;
    NSInteger row = indexPath.row;

    int howManyBefore = [[self.totalAtIndex objectForKey:BOX_INT(section)] intValue];
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row+howManyBefore inSection:0];

    NSManagedObject *obj = [_fetchedResultsController objectAtIndexPath:newIndexPath];

    // build and return cell

}

如果有人有更好的解决方案......