跨多个UITableViewCells拆分单个Core Data对象

时间:2015-03-13 16:14:06

标签: ios objective-c uitableview core-data

我有一个名为Drug的Core Data对象,它包含4个属性; drugEnabled,drugName,drugAdmin,drugExpire。

通过解析JSON文件预先填充Core Data对象,以便单个条目看起来像这样; “drugName":”药物1",“drugEnabled":true,”drugAdmin":" 1/1/90",“drugExpire":”1/1 / 00"

单节表有3个原型单元格。第一个是药物名称,还包含一个开关,用于隐藏或显示以下两个细胞,分别用于drugAdmin和drugExpire。前提是只有启用(打开)的药物才会显示其各自的管理和过期日期。将显示所有已禁用的drugName单元格,下方没有任何相应的日期。我可以通过以下方式用文字表示:

- Drug 1 (on)
- - Drug 1 Admin Date
- - Drug 1 Expire Date
- Drug 2 (on)
- - Drug 2 Admin Date
- - Drug 2 Expire Date
- Drug 3 (off)
- Drug 4 (off)
- Drug 5 (on)
- - Drug 5 Admin Date
- - Drug 5 Expire Date

因为我没有使用任何部分,并且因为每个对象分布在表中的3个不同的行中,所以我修改了numberOfRowsInSection,以便返回的fetchedResultsController.fetchedObjects计数乘以3,即

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.fetchedResultsController.fetchedObjects count] * 3;
}

然后我使用cellForRowAtIndexPath方法确定哪个内容属于哪个单元格,即

- (DrugTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    Drug *drug = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if (indexPath.row % 3 == 0) {
    static NSString *cellIdentifier = @"cellDrug”;
    DrugTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

        cell.drugName.text = drug.drugName;     
        return cell;
    }

    else if (indexPath.row % 3 == 1) {
    static NSString *cellIdentifier = @"cellAdmin";
    DrugTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

        cell.drugAdmin.text = drug.drugAdmin;       
        return cell;
    }

    else if (indexPath.row % 3 == 2) {
    static NSString *cellIdentifier = @"cellExpire";
    DrugTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

        cell.drugExpire.text = drug.drugExpire;     
        return cell;
    }

    else {
        // never returned
        return cell;
    }
}

为了完整起见,我也用以下方法设置了单元格高度;

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row % 3 == 0) {
        return 48;
    }

    else if (indexPath.row % 3 == 1) {
        return 38;
    }

    else if (indexPath.row % 3 == 2) {
        return 38;
    }

    else {
        return 100;
    }
}

我遇到的错误是在cellForRowAtIndexPath方法中 - 尽我所能确定 - Core Data返回的对象数与我UITableView中的行数不匹配。基本上,我正在使用5个Core Data对象并将它们分成15个不同的UITableViewCells。根据我实例化Drug对象的时间,我得到[_PFArray objectAtIndex:]: index (5) beyond bounds (5)或者得到no object at index 6 in section at index 0作为我的错误。我理解错误,但是我对如何解决它感到迷茫。

同样,此表背后的主要前提是能够通过开关隐藏和显示关联的行,并在单个节表中执行此操作。我无法找到任何揭秘这一点的例子,我认为我非常接近,但这个错误让我受到了挤压。有没有人看到有关显示单个节表的任何好的教程/建议,以便用户可以根据不同的标准隐藏和显示行?

2 个答案:

答案 0 :(得分:2)

如果某些单元格将打开(导致另外一个单元格)而其他单元格关闭(导致另外3个单元格),则索引路径计算将非常复杂。只使用indexPath.row中的模3将不会削减它。

另一种解决方案可能是将三个细胞合并为一个。你只需要两种细胞类型,"关闭"并且"扩展"。那么你就不必再考虑NSFetchedResultsController的索引路径算术了。

无论如何,您需要跟踪哪些单元格是打开的并且已展开。您只需在两个地方cellForRowAtIndexPathheightForRowAtIndexPath中对此进行说明即可。

答案 1 :(得分:0)

在调用

之前,您需要修复indexPath.row(因为您返回count * 3)
Drug *drug = [self.fetchedResultsController objectAtIndexPath:indexPath]

因此,您需要创建一个类似于

的新索引路径
NSIndexPath *adjustedIndexPath = [NSIndexPath indexPathForRow:indexPath.row / 3 inSection:indexPath.section];
Drug *drug = [self.fetchedResultsController objectAtIndexPath:adjustedIndexPath];