1

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

NSFetchedResultsController 正在获取数据库中的所有对象...

为了让那些没有开发帐户的人重新考虑,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;
}

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

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

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

4

1 回答 1

0

到目前为止,我发现的唯一解决方案是对 section 数组进行后解析,以查找特定索引处的前一个对象的数量。

        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

}

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

于 2012-10-12T08:07:27.900 回答