gpt4 book ai didi

ios - NSFetchedResultsController 预置行或部分

转载 作者:技术小花猫 更新时间:2023-10-29 10:13:35 25 4
gpt4 key购买 nike

我有一个用标准 NSFetchedResultsController 填充的 UITableView。但是我想在前面加上一行或一个部分(最好是行,但两者都可以。)

我现在可能看到这样做的唯一方法是在处理处理来自 NSFetchedResultsController 的数据的部分/行时手动重写所有 NSIndexPath,以欺骗它看到索引 0 处的部分并从索引 0 处的行开始. 然而,这似乎是一个非常糟糕的主意,很快就会让人感到困惑,所以我想最好避免这种情况。

这方面的一个很好的例子就是当您第一次启动官方 Twitter 应用程序时,我会引导您从好友列表中添加一些人。

Screenshot of Twitter app's suggestions page, with the relevant sections highlighted

红色部分几乎是我想要实现的,黄色部分我假设是同一部分中 NSFetchedResultsController 的结果(尽管它们的自定义样式可能是一个单独的部分。)

最佳答案

这可以用一种相当干净的方式来完成。

我假设您从使用 Apple 示例代码的标准 NSFetchResultsController 设置的标准 tableview 开始。

首先你需要两个效用函数:

- (NSIndexPath *)mapIndexPathFromFetchResultsController:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
indexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];

return indexPath;
}

- (NSIndexPath *)mapIndexPathToFetchResultsController:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
indexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section];

return indexPath;
}

这些应该是相当不言自明的——它们只是帮助我们处理添加额外行的问题,当我们想使用来自获取的结果 Controller 的索引路径来访问表时,或者当我们想以其他方式删除它时。

然后我们需要创建额外的单元格:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"MyCellId";

if (indexPath.section == 0 && indexPath.row == 0)
{
UITableViewCell *cell;
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.textLabel.text = NSLocalizedString(@"Extra cell text", nil);

return cell;
}

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}

[self configureCell:cell atIndexPath:indexPath];

return cell;
}

确保我们正确地配置它(configurecell 只会被来自获取结果 Controller 的单元格调用):

// the indexPath parameter here is the one for the table; ie. it's offset from the fetched result controller's indexes
- (void)configureCell:(SyncListViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
indexPath = [self mapIndexPathToFetchResultsController:indexPath];

id *obj = [fetchedResultsController objectAtIndexPath:indexPath];
<... perform normal cell setup ...>
}

并告诉 TableView 它存在:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger numberOfRows = 0;

if ([[fetchedResultsController sections] count] > 0) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
numberOfRows = [sectionInfo numberOfObjects];
}

if (section == 0)
numberOfRows++;

return numberOfRows;
}

并响应选择:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];

if (indexPath.section == 0 && indexPath.row == 0)
{
[self doExtraAction];
return;
}

... deal with selection for other cells ...

然后重新映射我们从结果 Controller 获得的任何更新:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;

indexPath = [self mapIndexPathFromFetchResultsController:indexPath];
newIndexPath = [self mapIndexPathFromFetchResultsController:newIndexPath];

switch(type) {
... handle as normal ...

关于ios - NSFetchedResultsController 预置行或部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10965098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com