Общее описание:
Чтобы начать с того, что работает, у меня есть UITableView
, который был помещен в Xcode-сгенерированное представление с помощью Interface Builder. Владелец файла вида настроен на подкласс, созданный Xcode, UIViewController
. В этот подкласс я добавил рабочие реализации numberOfSectionsInTableView: tableView:numberOfRowsInSection:
и tableView:cellForRowAtIndexPath:
, а Table View dataSource
и delegate
подключены к этому классу через File Owner в Interface Builder.
Вышеупомянутая конфигурация работает без проблем. Проблема возникает, когда я хочу переместить этот вид таблицы 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, приложение на основе View в Xcode и назовите ее
TableTest
- Откройте
TableTestViewController.xib
в Interface Builder и перетащитеUITableView
на предоставленную поверхность. - Подключите
UITableView
dataSource
иdelegate
-outlets к файловому владельцу, который уже должен представлять класс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 и Go, и вы должны увидеть слово
Hello
вUITableView
-
Теперь, чтобы попытаться переместить эту логику
UITableView
в отдельный класс, сначала создайте новый файл в Xcode, выбрав подклассUITableViewController
и вызовите классTableTestTableViewController
- Удалите приведенный фрагмент кода из
TableTestViewController.m
и поместите его вTableTestTableViewController.m
, заменив стандартную реализацию этих трех методов на наш. - В интерфейсе Builder в том же файле
TableTestViewController.xib
перетащитеUITableViewController
в основное окно IB и удалите новыйUITableView
объект, который автоматически появился с ним - Установите класс для этого нового
UITableViewController
вTableTestTableViewController
- Удалите привязки
dataSource
иdelegate
из существующего ранее работающегоUITableView
и повторно подключите те же самые два привязки к новомуTableTestTableViewController
, который мы создали. - Сохраняйте изменения, стройте и идите, и если вы получаете результаты, которые я получаю, обратите внимание, что
UITableView
больше не функционирует должным образом
Решение:
Еще несколько проблем с устранением неполадок и некоторая помощь от Форумы разработчиков iPhone, я документировал решение! Для основного подкласса UIViewController
проекта требуется выход, указывающий на экземпляр UITableViewController
. Для этого просто добавьте следующее в заголовок основного представления (TableTestViewController.h
):
#import "TableTestTableViewController.h"
и
IBOutlet TableTestTableViewController *myTableViewController;
Затем в интерфейсе Builder подключите новую розетку от File Owner к TableTestTableViewController
в главном окне IB. Никаких изменений не требуется в части пользовательского интерфейса XIB. Просто имея эту розетку на месте, даже если код пользователя не использует ее напрямую, она полностью устраняет проблему. Благодаря тем, кто помог, и кредитует BaldEagle на форумах разработчиков iPhone для поиска решения.