我在我的应用中使用UITableViewController
表格,我添加了NSFetchedResultsController
以提供要在表格中显示的数据(设置self
作为其代表)。
但是我想添加一个唯一的单元格作为表格的最后一个单元格,与NSFetchedResultsController
的谓词生成的项目无关,我希望这个单元格始终位于表格的底部。
我尝试在表格视图数据源中简单地将这些方法添加1:
- (NSUInteger)numberOfSectionsInTableView:(UITableView *)sender
{
return [[self.fetchedResultsController sections] count] + 1;
}
- (NSUInteger)tableView:(UITableView *)sender numberOfRowsInSection:(NSUInteger)section
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects] + 1;
}
然后捕获这样生成这个额外行的情况(该表只有1个部分):
- (UITableViewCell *)tableView:(UITableView *)sender
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [self.fetchedResultsController.fetchedObjects count]) {
//Generate the last cell in table.
} else {
//Generate the rest of the cells like normal.
}
return nil; //To keep the compiler happy.
}
这将检查索引是否是最后一个单元格并正确处理它。
但是我在运行时仍然收到以下错误:
*** Terminating app due to uncaught exception 'NSRangeException',
reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
知道是什么导致了这个吗?或者是否有更好的方法将额外的行添加到由NSFetchedResultsController控制的表视图中?
答案 0 :(得分:13)
如果您实现文档中指示的所有数据源方法(更新等),则获取的结果控制器与tableview紧密相关。它会变得相当混乱和黑客。
您的“额外行”可能是该表的页脚视图吗?这总是在底部。让它看起来像一个细胞并不是太多的工作,但从它的外观来看,你希望它看起来与其他细胞看起来不同。
答案 1 :(得分:2)
鉴于该表只有一个部分,这段代码看起来不对:
- (NSUInteger)numberOfSectionsInTableView:(UITableView *)sender
{
return [[self.fetchedResultsController sections] count] + 1;
}
我怀疑当tableview试图检索第二部分时你的崩溃了; + 1应该被移除。
使用来自获取结果控制器的表格可以做更复杂的事情(参见NSFetchedResultsController prepend a row or section),所以我确信这个简单的案例可以起作用。
答案 2 :(得分:0)
为什么不使用UITableView的内置页眉和页脚视图?
示例:
UIView *customBottomView = [UIView alloc] init... //set up your View (what you called custom bottom cell
)
self.table.tableFooterView = customBottomView; //或者tableHeaderView
从技术上讲,您正在添加一个视图,该视图显示在添加到表中并由TableView进行奇妙处理的表的下方(或上方)。对于用户,无法确定这是(最后一个)单元格还是仅仅是视图。如果你打算使用像didSelectRowAtIndexPath
这样的方法,你只需要解决答案 3 :(得分:0)
你绝对不想破解索引路径,并且标题不会,因为单元格有许多你不想丢失的优点。
所以Apple解决这个问题的方法首先要做一个超级实体。然后为要添加的行创建另一个新实体,并使其成为子实体。然后使您正在获取的现有行实体也成为子实体。然后将获取控制器的获取实体更改为此超级实体,这样它将返回结果中的两个子实体。在超级实体中添加sortOrder属性,并在要首先显示的行上将其设置为1,在所有其他行上将其设置为2,这就是使新行显示在顶部的原因。
这就是Apple在iOS Notes应用程序中实现文件夹列表视图的方式。获取控制器的实体是NoteContainer,2个子实体是Account和Folder。顶部的“All iCloud”行是一个帐户,其余的是文件夹。
NoteContainer (sortOrder)
- Account (1)
- Folder (2)
注意垃圾箱也是一个文件夹,但其排序顺序为3,因此最后显示。
这里更广泛的教训是根据您希望它们如何使用获取控制器在UI中显示您的实体,而不是像在规范化的关系数据库中那样。