Существуют и другие проблемы с кодом, помимо тех, о которых упоминал mrcrowl, теперь требующих "alloc-init" для выходов. В частности, эта строка:
cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] lastObject];
Это не типичная идиома, используемая для загрузки пользовательской ячейки табличного представления из .xib. Прежде всего, вы передаете «owner: self», что означает, что вы хотите соединить объекты розетки в файле .xib с элементами розетки в вашем tableviewcontroller объекте, возможно, не то, что вы предполагали.
Во-вторых, вы полагаетесь на порядок объектов, возвращаемых из loadNibNamed: owner: options:, который, хотя он может работать сегодня, может не работать завтра или в новой версии iOS.
Вместо этого обычная идиома состоит в объявлении выхода для всей ячейки табличного представления в вашем контроллере табличного просмотра:
(в файле .h):
...
UITableViewCell *tvCell;
...
@property (nonatomic, retain) IBOutlet UITableViewCell *tvCell;
Тогда вместо вашей строки, у вас есть это:
[[NSBundle mainBundle] loadNibNamed:@"NewsArchiveTitleTvCell" owner:self options:nil];
cell = tvCell;
self.tvCell = nil;
Обычно это делается не с помощью подклассов, обратите внимание, как я объявил класс не как CustomCell, а как ванильный UITableViewCell. Так как же получить эти надоедливые подпредставления, чтобы настроить их? Использование тегов является нормальным способом:
...
#define kMyKewlLabelTag 1
...
UILabel *kewlLabel = (UILabel *) [cell viewWithTag:kMyKewlLabelTag];
kewlLabel.text = [NSString stringWithFormat:@"Hi there from row %d!", indexPath.row];
...
EDIT:
редактировать: вот немного подробнее, комментарии слишком короткие, чтобы ответить на вопрос "что здесь происходит?" вопрос. Вот выдержка из одного из моих приложений, загружающего UITableViewCell из .xib:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"MyShoppingCartTvCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:@"ShoppingCartTvCell" owner:self options:nil];
cell = tvCell;
self.tvCell = nil;
}
...
// (insert code to grab model data for this row)
...
UILabel *nameLabel = (UILabel *) [cell viewWithTag:1];
nameLabel.text = itemNameStr;
UILabel *countLabel = (UILabel *) [cell viewWithTag:2];
countLabel.text = [NSString stringWithFormat:@"%d", itemCount];
UIImageView *iv = (UIImageView *) [cell viewWithTag:3];
...
Вот что здесь происходит:
Не существует пользовательского подкласса UITableViewCell, есть только файл .xib с именем «ShoppingCartTvCell.xib», содержащий UITableViewCell, и элементы пользовательского интерфейса, размещенные внутри UITableViewCell. Элементам пользовательского интерфейса, данные которых должны изменяться в каждой строке, присваивается уникальный тег (поле тега находится в Инспекторе атрибутов CMD-1 в IB), чтобы ваш код мог получить указатель на эти объекты, чтобы изменить их (настроить метки, изображения и т. Д.) , Убедитесь, что вы не используете «0», так как все элементы по умолчанию имеют тег 0. Также убедитесь, что поле «Идентификатор» UITableViewCell в Инспекторе атрибутов CMD-1 является строкой CellIdentifier.
Владелец файла .xib-файла - это ваш контроллер табличного представления, в котором вы хотите отобразить ячейку. Точнее, это может быть любой класс, содержащий IBOutlet UITableViewCell * tvCell; член. Это экземпляр этого класса, который вы передаете как владелец loadNibNamed: owner: options :. До тех пор, пока значение связанного выхода равно нулю в владельце, когда вы вызываете loadNibNamed: owner: options, выход владельца заполняется объектом из .xib (до тех пор, пока соединение было установлено в. хиб в иб). Понимание того, что это магический момент в программировании Apple, открывает перед вами совершенно новые перспективы:).
Вы должны установить self.tvCell = nil;
, чтобы подготовиться к следующему cellForRowAtIndexPath, который необходимо загрузить из .xib. Я также иногда устанавливаю nil перед loadNibNamed: owner: options :, я думаю, что это на самом деле немного безопаснее.
Вот как вы собираетесь загружать ваши UITableViewCells из .xib:
В xcode добавьте IBOutlet UITableViewCell * tvCell; в ваш класс UITableViewController (включая объявление свойства, если хотите)
В вашем проекте xcode создайте новый файл, пользовательский интерфейс, пустую Xib. Откройте этот .xib в IB
В IB перетащите TableViewCell из библиотеки в пустой файл .xib в поле «Первый ответчик»
Щелкните Владелец файла, CMD-4 (Identify Inspector), и в разделе «Класс» выберите класс, содержащий IBOutlet UITableViewCell * tvCell, который вы добавили (вероятно, ваш подкласс UITableViewController, класс, в котором вы управляете своей таблицей).
Удерживая клавишу Control, перетащите владелец файла в UITableViewCell и выберите розетку, которую хотите подключить. Это поле, в котором будет храниться UITableViewCell, недавно загруженный из xib, когда вы вызываете loadNibNamed: owner: параметры с экземпляром Владелец файла в качестве параметра "owner".
Добавление элементов пользовательского интерфейса в UITableViewCell (убедитесь, что они внутри иерархии UITableViewCell). Любые элементы, которые вы хотите настроить для каждой строки, требуют уникального значения тега.
следуйте рецепту, который я дал выше в cellForRowAtIndexPath
У вас есть волшебный момент, когда вы начинаете понимать, как файлы .xib и объекты-владельцы файла действительно работают вместе, и начинаете создавать множество классных UITableViewCells и других пользовательских объектов представления в IB, потому что это действительно просто и намного лучше, чем создавать их в коде (ИМНШО).