Общее описание:
Чтобы начать с того, что работает, у меня есть UITableView
, который был помещен в сгенерированный Xcode вид с помощью Interface Builder. Владелец файла представления установлен в сгенерированный XCode подкласс UIViewController
. К этому подклассу я добавил рабочие реализации numberOfSectionsInTableView: tableView:numberOfRowsInSection:
и tableView:cellForRowAtIndexPath:
, а таблицы dataSource
и delegate
подключены к этому классу через владельца файла в Интерфейсном Разработчике.
Приведенная выше конфигурация работает без проблем. Проблема возникает, когда я хочу переместить реализации dataSource
и delegate
этого табличного представления в отдельный класс, скорее всего из-за того, что есть другие элементы управления в представлении, кроме табличного представления, и я хотел бы переместить табличное представление связанный код для своего собственного класса. Для этого я пытаюсь сделать следующее:
- Создайте новый подкласс
UITableViewController
в Xcode
- Переместите зарекомендовавшие себя реализации
numberOfSectionsInTableView:
, tableView:numberOfRowsInSection:
и tableView:cellForRowAtIndexPath:
в новый подкласс
- Перетащите
UITableViewController
на верхний уровень существующего XIB в InterfaceBuilder, удалите UIView
/ UITableView
, которые автоматически создаются для этого UITableViewController
, затем установите UITableViewController
класс, соответствующий новому подклассу
- Удалите ранее работающие
UITableView
существующие dataSource
и delegate
соединения и подключите их к новым UITableViewController
По завершении у меня не работает UITableView
. В итоге я получаю один из трех результатов, которые могут казаться случайными:
- Когда загружается
UITableView
, я получаю сообщение об ошибке выполнения, указывающее, что я посылаю tableView:cellForRowAtIndexPath:
объекту, который его не распознает
- Когда загружается
UITableView
, проект без ошибок вырывается в отладчик
- Нет ошибки, но
UITableView
не появляется
С некоторой отладкой и созданием базового проекта только для воспроизведения этой проблемы я обычно вижу третий вариант выше (без ошибки, но без видимого табличного представления). Я добавил несколько вызовов NSLog и обнаружил, что, хотя numberOfSectionsInTableView:
и numberOfRowsInSection:
оба вызывают, cellForRowAtIndexPath:
нет. Я убежден, что упускаю что-то действительно простое и надеялся, что ответ может быть очевиден для кого-то с большим опытом, чем у меня. Если это не будет легким ответом, я был бы рад обновить с некоторым кодом или примером проекта. Спасибо за ваше время!
Полные шаги для воспроизведения:
- Создайте новую iPhone OS, приложение для просмотра в Xcode и назовите его
TableTest
- Откройте
TableTestViewController.xib
в Интерфейсном Разработчике и перетащите UITableView
на предоставленную поверхность просмотра.
- Подключите выходы
UITableView
dataSource
и delegate
к Владельцу файла, который уже должен представлять класс TableTestViewController
. Сохраните ваши изменения
- Вернувшись в Xcode, добавьте следующий код в
TableTestViewController.m:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Returning num sections");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"Returning num rows");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Trying to return cell");
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.text = @"Hello";
NSLog(@"Returning cell");
return cell;
}
Build and Go, и вы должны увидеть слово Hello
в UITableView
Теперь, чтобы попытаться переместить логику этого UITableView
в отдельный класс, сначала создайте новый файл в XCode, выбрав UITableViewController
подкласс и вызвав класс TableTestTableViewController
- Удалите приведенный выше фрагмент кода из
TableTestViewController.m
и поместите его в TableTestTableViewController.m
, заменив реализацию по умолчанию этих трех методов на нашу.
- Вернитесь в Интерфейсный Разработчик в том же файле
TableTestViewController.xib
, перетащите UITableViewController
в главное окно IB и удалите новый объект UITableView
, который автоматически пришел с ним
- Установить класс для этого нового
UITableViewController
в TableTestTableViewController
- Удалите привязки
dataSource
и delegate
из существующих ранее работающих UITableView
и заново соедините те же две привязки с новыми TableTestTableViewController
, которые мы создали.
- Сохраняйте изменения, Build and Go, и если вы получаете результаты, которые я получаю, обратите внимание, что
UITableView
больше не работает должным образом
Решение: С некоторыми дополнительными возможностями по устранению неполадок и помощью iPhone Developer Forums , я задокументировал решение! Основному подклассу UIViewController
проекта требуется выход, указывающий на экземпляр UITableViewController
. Для этого просто добавьте в заголовок основного представления следующее (TableTestViewController.h
):
#import "TableTestTableViewController.h"
и
IBOutlet TableTestTableViewController *myTableViewController;
Затем в Интерфейсном Разработчике подключите новый выход от Владельца файла к TableTestTableViewController
в главном окне IB. Никаких изменений не требуется в части пользовательского интерфейса XIB. Просто наличие этой розетки, даже если ни один пользовательский код не использует ее напрямую, полностью решает проблему. Спасибо тем, кто помог и поблагодарил BaldEagle на форумах разработчиков iPhone за поиск решения.