我试图弄清楚如何做一个向下钻取的表格视图。我已经设法从表格视图单元格转到详细视图,并且有很多关于如何使用情节提要完成的教程。
我想要做的是使用 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设备