Ответ 1
Это можно сделать довольно чистым способом.
Я предполагаю, что вы начинаете со стандартного представления таблицы со стандартным NSFetchResultsController, который использует образец кода Apple.
Сначала вам понадобятся две служебные функции:
- (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;
}
Они должны быть достаточно понятными - они просто помощники, чтобы иметь дело с добавлением дополнительной строки, когда мы хотим использовать указательный путь из выбранных контроллеров результатов для доступа к таблице или удаления ее при переходе в другую сторону.
Затем нам нужно создать дополнительную ячейку:
- (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 будет вызываться только для ячеек из контроллера результатов выборки):
// the indexPath parameter here is the one for the table; ie. it offset from the fetched result controller indexes
- (void)configureCell:(SyncListViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
indexPath = [self mapIndexPathToFetchResultsController:indexPath];
id *obj = [fetchedResultsController objectAtIndexPath:indexPath];
<... perform normal cell setup ...>
}
и сообщите, что он существует:
- (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 ...
а затем переназначьте все обновления, которые мы получаем от контроллера результатов:
- (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 ...