Несколько пользовательских строк UITableView?

Я много искал, но не нашел ничего полезного, связанного с несколькими пользовательскими строками, мне нужно создать таблицу настроек для моего приложения, в которой мне нужно загрузить строки из файлов xib, например:

РЯД 1 =>> XIB 1.
РЯД 2 =>> XIB 2.
РЯД 3 =>> XIB 3.
РЯД 4 =>> XIB 4.

Мой текущий код:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell=nil;
    //We use CellType1 xib for certain rows
    if(indexPath.row==0){
        static NSString *CellIdentifier = @"ACell";
        cell =(ACell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if(cell==nil){
            NSArray *nib= [[NSBundle mainBundle] loadNibNamed:@"ACell" owner:self options:nil];
            cell = (ACell *)[nib objectAtIndex:0];
        }
        //Custom cell with whatever
        //[cell.customLabelA setText:@"myText"]
    }
    //We use CellType2 xib for other rows
    else{
        static NSString *CellIdentifier = @"BCell";
        cell =(BCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if(cell==nil){
            NSArray *nib= [[NSBundle mainBundle] loadNibNamed:@"BCell" owner:self options:nil];
            cell = (BCell *)[nib objectAtIndex:0];
        }
        //Custom cell with whatever
        //[cell.customLabelB setText:@"myText"]
    }

    return cell;
}

person Mateus    schedule 05.05.2012    source источник


Ответы (2)


Сначала вы создаете несколько пользовательских классов UITableViewCell (.h и .m), столько, сколько у вас есть xib-файлов:
Таким образом, вы можете иметь, например, CellType1 и CellType2.
CellType1.h будет выглядеть примерно так

#import <UIKit/UIKit.h>
@interface CellType1 : UITableViewCell

@property(nonatomic,strong) IBOutlet UILabel *customLabel;

@end

Затем вы создаете xib-файлы, вы можете использовать тип представления по умолчанию, но затем просто удалите автоматически созданное представление, замените его на UITableViewCell и измените класс на CellType1. Сделайте то же самое для CellType2.

Затем в вашем tableViewController напишите cellForRow следующим образом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell=nil;
//We use CellType1 xib for certain rows
if(indexPath.row==<whatever you want>){
     static NSString *CellIdentifier = @"CellType1";
     cell =(CellType1*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if(cell==nil){
        NSArray *nib= [[NSBundle mainBundle] loadNibNamed:@"CellType1" owner:self options:nil];
        cell = (CellType1 *)[nib objectAtIndex:0];
      }
      //Custom cell with whatever
      [cell.customLabel setText:@"myText"]
}
//We use CellType2 xib for other rows
else{
    static NSString *CellIdentifier = @"CellType2";
    cell =(CellType2*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if(cell==nil){
        NSArray *nib= [[NSBundle mainBundle] loadNibNamed:@"CellType2" owner:self options:nil];
        cell = (CellType2 *)[nib objectAtIndex:0];
      }
      //Custom cell with whatever
      [cell.customLabel setText:@"myText"]
}

return cell;
}
person JP Hribovsek    schedule 05.05.2012
comment
Что вы имеете в виду под ‹все, что вы хотите› - person Mateus; 05.05.2012
comment
Вы говорите, что хотите использовать несколько Xib, я предполагаю, что xib1 для строки n1, xib2 для строки n2 и т. д. Таким образом, оператор if/else проверяет индекс строки и на основе того, чего вы хотите достичь, вы выбираете правильный xib в правильном индексе строки - person JP Hribovsek; 05.05.2012
comment
Должен ли я изменить основной вид моего XIB для UITableViewCells или просто изменить размер представления? - person Mateus; 06.05.2012
comment
Просто удалите это представление и добавьте UITableViewCell, затем измените тип с UITableViewCell на WhateverCustomCell. - person JP Hribovsek; 06.05.2012
comment
Ваш код все еще не работает для меня! Не могли бы вы помочь мне еще немного, мне это действительно нужно. Я обновлю свои вопросы и добавлю код, который я пытаюсь сейчас! - person Mateus; 06.05.2012
comment
Не совсем уверен, что вы подразумеваете под неработающим, вам нужно уточнить, есть ли у вас ошибки компиляции или что происходит? Во-первых, я могу сказать вам, чтобы проверить, что XIB, содержащий ваше табличное представление, имеет выходы делегата и источника данных для владельца файла, который должен быть файлом с кодом cellForRow - person JP Hribovsek; 06.05.2012
comment
Вы можете размещать вещи здесь. В противном случае я создал быстрый проект, который использует пару xib для ячеек табличного представления, прямо здесь github.com/objectiveapp/ MultipleXibTableView - person JP Hribovsek; 06.05.2012

Если вы еще не знакомы с загрузкой пользовательской ячейки из xib, ознакомьтесь с документация здесь. Чтобы расширить это до нескольких пользовательских xib, вы можете создать каждую ячейку таблицы в отдельном xib, присвоить ей уникальный идентификатор ячейки, установить контроллер табличного представления в качестве владельца файла и подключить каждую ячейку к пользовательскому выходу ячейки, который вы определяете (в docs, они используют tvCell в качестве выхода). Затем в вашем методе -tableView:cellForRowAtIndexPath: вы можете загрузить правильный xib (или удалить из очереди правильную повторно используемую ячейку), проверив, для какой строки вы предоставляете ячейку. Например:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *MyIdentifier1 = @"MyIdentifier1";
    static NSString *MyIdentifier2 = @"MyIdentifier2";
    static NSString *MyIdentifier3 = @"MyIdentifier3";
    static NSString *MyIdentifier4 = @"MyIdentifier4";

    NSUInteger row = indexPath.row

    UITableViewCell *cell = nil;

    if (row == 0) {
        cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifer1];
        if (nil == cell) {
            [[NSBundle mainBundle] loadNibNamed:@"MyTableCell1" owner:self options:nil];
            cell = self.tvCell;
            self.tvCell = nil;
        }
    }
    else if (row == 1) {
        cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifer2];
        if (nil == cell) {
            [[NSBundle mainBundle] loadNibNamed:@"MyTableCell2" owner:self options:nil];
            cell = self.tvCell;
            self.tvCell = nil;
        }
    }
    else if (row == 2) {
        cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifer3];
        if (nil == cell) {
            [[NSBundle mainBundle] loadNibNamed:@"MyTableCell3" owner:self options:nil];
            cell = self.tvCell;
            self.tvCell = nil;
        }
    }
    else if (row == 4) {
        cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifer4];
        if (nil == cell) {
            [[NSBundle mainBundle] loadNibNamed:@"MyTableCell4" owner:self options:nil];
            cell = self.tvCell;
            self.tvCell = nil;
        }
    }
    // etc.

    // Do any other custom set up for your cell

    return cell;

}
person Sean    schedule 05.05.2012
comment
Этот метод не работает для меня. Я получаю «UITableView dataSource должен вернуть ячейку из tableView:cellForRowAtIndexPath:» Мысли? У меня есть мой ViewController, связанный с каждой ячейкой, и настраиваемый IBOutlet для каждой ячейки, созданный и подключенный к ячейке. - person Luke Irvin; 15.08.2013