在我的甜蜜应用程序中,您可以使用项目列表中的两种项目。有物品和袋子物品。导航到清单屏幕时,表视图有两个部分,每个部分有4个单元格。四个单元格用于装备物品,四个单元格用于“包”中的物品。如果你没有装备任何东西,细胞就会说“空”。
如何根据结果对象的形状有条件地填充表格单元格?
以下是我希望的代码:
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// this returns 'nil' if the index path was out of bounds
NSManagedObject * item = [self.fetchedResultsController carefullyGetObjectAtIndexPath:indexPath];
if (nil == item) {
cell.textLabel.text = @"empty";
} else {
cell.textLabel.text = [item valueForKey:@"name"];
}
}
我在尝试实现这个'小心'objectAtIndexPath:
时遇到了一些问题我尝试了边界检查,但我遇到了麻烦,因为fetchedArray是平的,而我试图导航的概念模型并不平坦:行是'in'部分。
我尝试使用try / catch,但后来我记得越界的元素是未定义的,而不是nil ...所以有时我得到一个错误,我可以捕捉并做出反应,有时我只是得到随机有趣的东西。我现在的设置:
@try {
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
return managedObject;
}
@catch (NSException * e) {
return nil;
}
一直给我5个条目,4个在正确的位置,1个奇数球,这是另一个部分的重复。
不确定如何手动导航所提取的结果。我正在玩四种,每种都有两种。我曾希望它会像双重嵌套数组一样容易,外部的部分和内部的行。似乎事情比这更棘手。当我检查fetchedResults NSArray时,我发现它是扁平的。所有的“包”物品都是第一个,“装备”是下一个。我不认为我可以依赖这种顺序,所以我觉得使用映射函数从indexPath部分到数组索引是不安全的。 (我可以确信这对此感到安全。)
我想到的一个替代方法是将8个“空”项目填充到我的库存中,当这些部分未完全填满时,这些项目将作为占位符结果返回。但这并不适合我。
我意识到为什么这不起作用:表不应该有'空'行。但我希望我的桌子有空行!
更新
这是我现在使用的方法......
- (NSManagedObject*) carefullyGetObjectAtIndexPath:(NSIndexPath*)indexPath
{
NSLog(@"in %@ %s", [self class], _cmd);
NSString * desiredType = (indexPath.section == BAG_SECTION)? @"bag" : @"equipable";
NSArray * fetchedObjects = [self.fetchedResultsController fetchedObjects];
NSInteger sectionStartIndex = -1;
// iterate until you hit a type you like
NSUInteger i, count = [fetchedObjects count];
for (i = 0; i < count; i++) {
NSObject * obj = [fetchedObjects objectAtIndex:i];
NSString * fetchedType = (NSString*)[obj valueForKey:@"type"];
if ([desiredType isEqualToString:fetchedType]) {
sectionStartIndex = i;
break;
}
}
if (-1 == sectionStartIndex) {
// maybe there aren't any of that type of item
} else {
NSInteger calculatedEntityIndex = sectionStartIndex + indexPath.row;
NSLog(@"calculated index %d", calculatedEntityIndex);
// if we are still in the array
if (calculatedEntityIndex < [fetchedObjects count]) {
// then we can get the object
NSManagedObject * entity = [fetchedObjects objectAtIndex:calculatedEntityIndex];
// and if we are still in the right section
NSString * typeForEntityAtIndex = [entity valueForKey:@"type"];
if ([desiredType isEqualToString:typeForEntityAtIndex]) {
// then this is what we wanted
return entity;
}
}
}
return nil;
}
我真的不觉得我应该迭代这样的事情......
Ž。
完全披露:这是一个学期项目,但该项目是以任何必要的方式制作应用程序。这包括第三方图书馆,在stackoverflow上提问,&amp; c ...这个学期项目的目标是体验更大的事情,比如甜蜜的应用程序,而不是学习目标-c。
答案 0 :(得分:1)
齐格,
NSFetchedResultsController
有很多限制。如果您无法使您的架构满足其严格的要求而且看起来您可能没有,那么您应该构建多个tableView
中的NSFetchRequest
。这很简单。大多数有趣的tableView
都是这样做的。当您执行更大的提取然后使用集合类上的set和filter操作优化搜索时,Core Data确实最有效。
tableView
可以有空行。您只需要在各种委托和单元配置代码中使用自定义代码进行协调。
您有很多选择来解决您的问题。看来你对一个非常有限的框架API不满意。你是一个崭露头角的程序员。滚动你自己。
安德鲁
P.S。您有一个好奇的目标是编写Mac OS X / iOS应用程序而无需学习Objective-C。实际上,您已经选择了框架中的一种技术Core Data,它可以将Objective-C运用到其最大功能。 (在我看来,作为iOS程序员的教育者,你的教育可能会更好地学习一个非常不同的持久性模型,Core Data的模型的复杂性,而不是退回到平凡的主流SQL解决方案。)如果你更愿意使用不同的语言,MacRuby / RubyMotion非常有效。