Приложение UITableView для прокрутки
Предисловие. Я новичок в iPhone SDK, Obj-C, Interface Builder и Cocoa. Я, вероятно, делаю что-то явно неправильное.
Вопрос:
У меня есть UITableView
, который падает, если я прокручиваю его. Он немного прокрутит, чтобы показать полную ячейку нижней половины скрытой ячейки, но не загрузит следующую. Точно так же, если я прокручиваю верхнюю часть, чтобы полностью скрыть нижнюю часть ячейки, и резиновые ленты вернутся, чтобы показать эту ячейку, она будет разбиваться, прежде чем показывать ее. Это кажется мне странным, потому что он правильно рисует первые 7 из 11 ячеек. Данные ячейки находятся в NSArray
, в UITableViewController
, связанных как как dataSource
, так и delegate
для UITableView
в Interface Builder. Он работает, когда представление инициализируется.
Я создаю приложение. Я думал, что мне будет сделано 2 дня назад, которое просто вычисляет комбинации и отображает их список в том, что, по моему мнению, было бы удобным просмотром таблицы прокрутки. Прямо сейчас, он даже не вычисляет все, NSArray
в dataSource
инициализируется один раз с некоторыми строками типа @"Hello"
и @"World"
.
Шаги по воспроизведению:
Поскольку я использую IB, я не могу точно показать вам всю историю в коде. Поэтому я расскажу, что я сделал до сих пор, и надеюсь, что это не сделает вас сонными.
Создал новое приложение "Tab Bar Application" в Xcode, потому что мне нужно 2 вкладки, и мне не нужна панель навигации или полноэкранная таблица. Я переместил представление первой вкладки MainWindow.xib
в FirstView.xib
как аналог данного SecondView.xib
. Это сработало хорошо. Я изменил представление, чтобы содержать два UITextField
для входов, и UITableView
для вывода. Это работало, но таблица была пустой. Я подклассифицировал UITableViewController
, в котором я заполнил свойство NSArray
с именем combinations
с помощью 11 строк, а затем добавил
// Set up the cell...
cell.userInteractionEnabled = NO;
cell.text = [combinations objectAtIndex:indexPath.row];
где был только комментарий. В IB я добавил Table View Controller
в FirstView.xib
и установил его имя класса в соответствие с именем этого нового подкласса и перетащил Table View
на мой взгляд на этот Combinations Table View Controller
дважды. После связывания dataSource
и после delegate
. Хотя я получаю такое же поведение, если привязан только к dataSource
.
Это выполняется и заполняет таблицы видимыми строками (6.5) с помощью первых 7 значений в dataSource
combinations
. Я могу прокрутить 0.5 ячейки вниз, а затем вернуться обратно. Но если я прокручу более 0,5 ячеек вверх или вниз, приложение выйдет из строя. Объяснение в отчете гласит:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSCFTimer tableView:cellForRowAtIndexPath:]:
unrecognized selector sent to instance 0x52ca40'
Я не делал NSCFTimer
и не связывал его с моим Table View
, я подозреваю, что cellForRowAtIndexPath
- это именно сообщение, которое должно было отправиться на мой dataSource
или delegate
, поэтому я ' m запутался в том, почему он сбился с пути и где он закончился.
Обновить. Спасибо за ответы и комментарии. Моя проблема заключается в том, что CombinationsTableViewController
(подкласс UITableViewController
) на самом деле не создан каким-либо конкретным местом в моем коде. Он создается как некоторое время (когда загружается FirstView.xib
) и, по-видимому, управляется, в то время как начальный tableView заполняется 7 ячейками и затем освобождается. Поэтому мне нужно определить, где/как сделать сохраненную ссылку на этот контроллер. Мой Application Delegate
должен, вероятно, иметь некоторый выход, который содержит этот контроллер, который может быть связан как экземпляр, который находится в xib
. Да, я новичок в этом. Я знаю, что я мог бы просто устранить эти проблемы, избегая IB и делая вещи явно в коде, но я полагаю, что хочу научиться гибко использовать IB.
Наконец: Да, мне нужен сохранившийся экземпляр контроллера табличного представления. Это звучит элементарно, но это было непонятно при работе с IB, как у меня. Прочитайте мой собственный пост для всего процесса и исправьте.
Помимо: либо отладчик нуждается в подробных инструкциях (любые ссылки оцениваются), либо он работает не очень хорошо. Кажется, я быстрее получаю больше информации, позволяя аварийному завершению работы приложения и чтению отчета, который он создает. Но для этого требуется утомительное завершение, перезапуск и 3 щелчка. Я действительно хотел перейти от этого к подключению входов, выполнению вычислений и обновлению таблицы при каждом изменении. Это должно быть тяжелой частью, а не тем, что делает работу члена фреймворка.
Дальнейшее движение: все это было в iPhone SDK для версии 2.2.1. В то время iPhone OS 3.0 не бета-версия еще не была доступна, не вступая в клуб за холодные наличные деньги. Я ожидал, что он будет открыт на WWDC 2009, но на самом деле сегодня (17 июля 2009 года) был выпущен бесплатный общедоступный 3.0 SDK.
Ответы
Ответ 1
Итак, если вы выполнили действия по воспроизведению, я добавлю следующие шаги для решения этой проблемы:
Шаги по устранению этой проблемы
-
Подкласс a UIViewController
. Я позвонил в мой CombinationsViewController
. В этом контроллере добавьте свойство как IBOutlet для combinations
Table
ViewController
с шага 6 ниже.
-
Не забудьте импортировать нужный материал и синтезировать контроллер табличного представления, также отпустите его в методе dealloc
.
-
В FirstView.xib
измените класс File Owner
на этот последний подкласс.
-
Свяжите комбинацию каналов ControlController с Combinations Table View Controller
в FirstView.xib
, сделанном на шаге 7 ниже.
-
Откройте TabBarController
в MainWindow.xib
, выберите первую вкладку, а в Identity Inspector измените класс на последний подкласс (CombinationsViewController
).
Это заставляет таблицу нормально заполнять и прокручивать материал.
Теперь я собираюсь двигаться дальше и получить какое-то пользовательское поведение в виде таблицы, и на самом деле заставить мое приложение сделать что-нибудь.
Перечисленные шаги для воспроизведения в качестве ссылки на исправление:
-
Создал новое приложение "Tab Bar Application" в Xcode.
-
Открыл Tab View Controller
, перетащил представление prefab для первой вкладки в MainWindow.xib
-
Создал новый xib, основанный на представлении, под названием FirstView.xib
в качестве аналога с данным SecondView.xib
, и поместил этот предварочный просмотр в этот xib.
-
Связано представление с выходом File Owner
view
.
-
Я изменил представление на два входа UITextField
для входов и UITableView
для вывода.
-
Я подклассифицировал UITableViewController
как CombinationsTableView
, в котором я заполнил свойство NSArray
с именем combinations
с помощью 11 строк, а затем добавил код cell.text = [combinations objectAtIndex:indexPath.row];
, где был только комментарий о настройке ячейка.
-
В FirstView.xib
я добавил Table View Controller
и установил его имя класса в соответствии с именем этого нового подкласса и перетащил Table View
в мой взгляд на этот Combinations Table View Controller
дважды. После связывания dataSource
и после delegate
.
В этот момент таблица выполняет рендеринг с данными, но прокрутка прорывается. Это связано с тем, что CombinationsTableView не сохраняется нигде. И это очень непонятно для первого пользователя IB. Поэтому вам необходимо применить исправление, указанное выше.
Первый человек, который суммирует это в своем ответе, получает правильную метку ответа. НАПРИМЕР. Создайте подкласс viewController, который является владельцем файла FirstView.xib и содержит сохраненный IBOutlet, который вы можете связать с контроллером табличного представления в том же файле xib.
Ответ 2
похоже, что вы теряете делегата tableView.
Похоже, что это происходит, когда UITableViewDelegate освобождается, и приложение затем использует тот же адрес указателя для NSCFTimer.
Вы вызвали выпуск на своем деле в любом месте, или вы не сохранили делегата, если он находится в пуле автозапуска.
Ответ 3
Причина, по которой загружается первая ячейка, заключается в том, что tableview предварительно загружает, как и другие ячейки, которые находятся на экране.
Все ячейки загружаются из метода источника данных:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Я бы удостоверился, что вы явно задали делегат и источник данных tableView. Это можно сделать в коде или IB. по:
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
Кроме того, как сказал Bluephlame, вы можете где-то освобождать UITableVewController.
Чтобы узнать, установите точку останова в методе dealloc:
- (void)dealloc{
//releasing things
[super dealloc];
}
Если вы отпустите его, вы попадете в эту точку останова. Затем вы можете начать отслеживать виновника.
Ответ 4
У меня была такая же проблема и исправлена ее добавлением nil в массив в качестве последнего элемента.
Он рушился для этого:
pairs = [[NSArray alloc] initWithObjects:@"EUR/USD",@"USD/JPY",@"GBP/USD",@"USD/CHF",@"USD/CAD"];
но не для этого:
pairs = [[NSArray alloc] initWithObjects:@"EUR/USD",@"USD/JPY",@"GBP/USD",@"USD/CHF",@"USD/CAD",nil];
Надеюсь, что это поможет.
Ответ 5
выделяет память в массив вместо [NSArray arrayWithObjects:];
. Без выделения памяти он не перезагружает строки.... используйте array=[NSArray alloc] initWithObjects];
... вместо указанного выше.
Ответ 6
У меня была такая же проблема. У меня был подкласс класса UITableViewController в файле nib, но я только объявил UITableView как свойство outlet/, которое был выпущен tableview UITableViewController, когда он все еще используется.
Быстрое исправление было просто добавить выход к классу File Owner, который ссылался на встроенный UITableViewController.