如何从获取的结果对象中填充稀疏的 UITableView?
Posted
技术标签:
【中文标题】如何从获取的结果对象中填充稀疏的 UITableView?【英文标题】:How can I populate a sparse UITableView from a fetched results object? 【发布时间】:2012-07-01 04:35:51 【问题描述】:在我的甜蜜应用中,您可以使用项目列表中的两种项目。有可装备的物品和袋子物品。当您导航到清单屏幕时,表格视图有两个部分,每个部分有 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;
我真的觉得我不应该重复这样的事情......
z.
完全披露:这是一个长期项目,但该项目是通过任何必要的方式制作应用程序。这包括第三方库、在 *** 上提问等...本学期项目的目标是体验在更大的东西上工作,比如一个甜蜜的应用程序,而不是学习 Objective-c。
【问题讨论】:
在这里查看自定义表格视图,cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html 【参考方案1】:齐格,
NSFetchedResultsController
有很多限制。如果您不能使您的架构满足其严格的要求并且您可能没有,那么您应该从多个NSFetchRequest
s 中构造您的tableView
。这很简单。大多数有趣的tableView
s 就是这样做的。当您执行较大的提取然后使用集合类上的集合和过滤操作细化搜索时,Core Data 确实工作得最好。
tableView
s 可以有空行。您只需将其与各种委托和单元配置代码中的自定义代码进行协调即可。
您有很多选择来解决您的问题。看来您对非常有限的框架 API 不满意。你是一个初出茅庐的程序员。自己动手。
安德鲁
附:您有一个奇怪的目标,即编写一个 Mac OS X/ios 应用程序,而无需学习 Objective-C。您实际上已经选择了框架中的一项技术,即 Core Data,它可以最大限度地发挥 Objective-C 的能力。 (在我看来,作为 iOS 程序员的教育者,学习一个非常不同的持久性模型(Core Data 的模型)的复杂性可能会比退缩到平凡的主流 SQL 解决方案更好。)如果你更喜欢使用不同的语言,MacRuby/RubyMotion 相当有效。
【讨论】:
值得深思的好食物!顺便说一句,不学习 Objective-C 不是我的目标:我喜欢 Objective-C,我喜欢学习新语言。我只是想澄清一下,回答这个问题不会与作业标签冲突(因为问题来自作业而不是作业本身)。以上是关于如何从获取的结果对象中填充稀疏的 UITableView?的主要内容,如果未能解决你的问题,请参考以下文章