我试图弄清楚如何做一个向下钻取的表格视图。我已经设法从表格视图单元格转到详细视图,并且有很多关于如何使用情节提要完成的教程。
我想要做的是使用 plist 在表格视图中列出一些数据 - 我的那部分工作正常。我现在想做的就是往下走几个层次。例如:
Top level --> Level 1 --> level 2 --> etc --> detailed view. 
现在我似乎能做的就是:顶级-> 详细视图。
我只需要了解如何 - 当点击一个单元格时,它将在下一级加载该单元格的数据 - 就像某种类别一样。
我正在使用 iOS7 SDK 和 Xcode 5。
编辑:
所以我查看了其他一些教程并根据我的需要对其进行了修改——这是我需要做的,也是我正在做的:
- 我正在使用模型对象——它们从 Plist 中获取数据,其中根对象是字典。
- Plist中的数据是这样的: - <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>name</key> <string>iDevices</string> <key>devices</key> <array> <dict> <key>name</key> <string>iPhones</string> <key>devices</key> <array> <dict> <key>name</key> <string>1St Generation</string> </dict> </array> </dict> <dict> <key>name</key> <string>iPads</string> <key>devices</key> <array> <dict> <key>name</key> <string>1St Generation</string> </dict> </array> </dict> </array> </dict> </plist>
所以现在我将 Plist 加载到一个自定义数据对象中,然后我使用这个对象来填充一个 NSMutableArray,如下所示:
-(void)loadData{
    NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"masterDeviceList" ofType:@"plist"];
    NSDictionary *deviceListDict = [NSDictionary dictionaryWithContentsOfFile:plistPath];
    NSArray *allDevices = deviceListDict[@"devices"];
    NSMutableArray *iDevices = [NSMutableArray array];
    for (NSDictionary *dictionary in allDevices){
        RCDevice *iDevice = [[RCDevice alloc]initWithDictionary:dictionary];
        [iDevices addObject:iDevice];
    }
        self.devices = iDevices;
}
我从根 TVC 上的 viewDidLoad 调用此方法。数据正确加载。
然后我像这样填充tableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell* cell;
    RCDevice *iDevice = self.devices[indexPath.row];
    if (iDevice.device) {
        cell = [tableView dequeueReusableCellWithIdentifier:LoopBackCell];
    } else {
        cell = [tableView dequeueReusableCellWithIdentifier:DetailCell];
    }
    cell.textLabel.text = iDevice.name; 
    return cell;
}
然后这就是我卡住的地方:
   - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UITableViewCell *cell = (UITableViewCell *)sender;
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    NSDictionary *rowData = self.devices[indexPath.row]; //Testing with this type
    RCDevice *iDevice = self.devices[indexPath.row]; //Also testing with custom object
    if ([self.devices[indexPath.row]isKindOfClass:[NSDictionary class]])
        {
        if ([segue.identifier isEqualToString:@"loopbackSegue"]) {
            RCDeviceListView *rcDeviceListVC = (RCDeviceListView *)segue.destinationViewController;
                //TODO: Check if this gets called
            }else if ([segue.identifier isEqualToString:@"detailSegue"]){
                __unused RCDeviceDetailView *rcDeviceDVC = (RCDeviceDetailView *)segue.destinationViewController;
                    //TODO Fille this in!
        }
        }
    else {
        if ([self.devices[indexPath.row]isKindOfClass:[RCDevice class]])
            {
            if ([segue.identifier isEqualToString:@"loopbackSegue"]) {
            RCDeviceListView *rcDeviceListVC = (RCDeviceListView *)segue.destinationViewController;
                rcDeviceListVC.devices = iDevice.device; //This crashes
                rcDeviceListVC.devices = rowData[@"devices"]; //Also crashes
                rcDeviceListVC.title = iDevice.name;
            }else if ([segue.identifier isEqualToString:@"detailSegue"]){
                __unused RCDeviceDetailView *rcDeviceDVC = (RCDeviceDetailView *)segue.destinationViewController;
            }
            }       //TODO Fille this is!
            }
}
该应用程序因以下行而崩溃:
rcDeviceListVC.devices = rowData[@"devices"]; 
我得到的错误:
[*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[RCDevice objectForKeyedSubscript:]:无法识别的选择器发送到实例 0xed4aff0”
我明白为什么 - 我认为:
rcDeviceListVC.devices
是一个用我的 loadData 方法填充的 RCDevice 对象的数组 - 它不知道是什么rowData[@"devices"]。
所以我试图用这个来修改它:
rcDeviceListVC.devices = iDevice.device; 
但这意味着我有一个不兼容的指针。(NSString 到 NSArray)
我不知道如何解决这个问题。我认为是因为我不完全理解 prepareForSegue 方法在做什么?
对于实际的向下钻取 - 我正在使用环回 segue 并重用 RCDDeviceListVC。
该应用程序现在做什么:
- 它在 Tableview 中加载正确的数据。当我选择一个单元格时 - prepareForSegue 方法被调用 - 应用程序崩溃。
或者
- 它使用顶级数据重新加载表视图,并具有永无止境的向下钻取(循环)
我希望应用程序做什么:
使用它现在使用的数据(iPhone、iPad)加载第一个 tableview - 点击一个单元格将列出 iPad 或 iPhone 的型号。
我究竟做错了什么?
更新:
这是我尝试编辑以与我的自定义对象一起使用的原始代码示例 - 而不是使用 NSDictionaries。
我用我的 Plist 测试了这个代码示例,它完全按照我的需要工作:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    UITableViewCell* cell = (UITableViewCell*)sender;
    NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
    NSDictionary* rowData = [self.items objectAtIndex:indexPath.row];
    if ([segue.identifier isEqualToString:@"loopbackSegue"]) {
        DrillTableController* drillVC = (DrillTableController*)segue.destinationViewController;
            drillVC.items = [rowData objectForKey:@"items"];
        drillVC.title = [rowData objectForKey:@"name"];
    } else if ([segue.identifier isEqualToString:@"detailSegue"]) {
        DetailsController* detailVC = (DetailsController*)segue.destinationViewController;
        detailVC.name = [rowData objectForKey:@"name"];
        //detailVC.imageName = [rowData objectForKey:@"imageName"];
    }
}
为什么它适用于上述 - 但不是当我尝试使用我的自定义对象时?
RC设备