Копирование UITableViewCell

голоса
7

Я читаю пользовательскую ячейку таблицы в tableView:cellForRowAtIndexPath:из файла СИБА. Это прекрасно работает для моих целей, за исключением того, что это довольно медленно.

Теперь, я знаю, что нужно делать в долгосрочной перспективе создать ячейку целиком в коде, и использовать один вид, и так далее. Но это прототип, и я не хочу, чтобы положить, что много усилий в него.

На данный момент, я был бы счастлив , если бы я читал перо только один раз в UIViewControllerподклассе, а затем tableView:cellForRowAtIndexPath:сделал копии. Мое предположение о том , что копирование будет быстрее , чем чтение пера.

Вот что я использую , чтобы загрузить перо, которое я называю из viewDidLoad:retainпосле)

-(id)loadFromNamed:(NSString*)name {
    NSArray *objectsInNib = [[NSBundle mainBundle] loadNibNamed:name
                                                          owner:self
                                                        options:nil];
    assert( objectsInNib.count == 1 );
    return [objectsInNib objectAtIndex:0];
}

Все это хорошо до сих пор. Но возникает вопрос: Как скопировать это снова и снова? Возможно ли это?

Я попробовал [_cachedObject copy]и , [_cachedObject mutableCopy]но UITableViewCellне поддерживает ни протокол копирования.

Если у меня есть, я могу только сказать им, чтобы игнорировать скорость, пока я не готов удалить перо полностью, но я предпочел бы получить это происходит немного быстрее, если есть низко висящие фрукты здесь.

Есть идеи?

Задан 20/02/2009 в 21:43
источник пользователем
На других языках...                            


5 ответов

голоса
8

Я думаю, справляясь из ячейки таблицы может быть использован вместе с механизмом извлечения из очереди, что позволит создать клетку один раз (от кончика пера или программного способом или при получении его автоматически загружается из другого заостренного наконечника и связывающие как выход в IB), а затем клонировать его или из очереди его при необходимости.

UITableViewCell не соответствует протоколу NSCopying, но он поддерживает архивацию шпоночную / разархивирования механизм, поэтому его можно использовать для клонирования.

«На основании ответа ? Как дублировать UIButton в Objective C » мой метод источника данных делегата выглядит следующим образом :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellID = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];

    if (!cell) {
        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
        cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
    }

    // ... config ...

    return cell;
}

И в моем случае self.tableViewCell является клетка , которая была загружена один раз из файла СИБ вида.

Я не проверял , что будет быстрее: «архив + разархивировать» клонировать или «загрузить файл СИБ + разархивировать» , который структура будет делать в случае -loadNibNamed: Владелец: варианты: я использовал этот метод только с соображениями удобства, но хорошие шансы , что операция памяти против операции файла будет быстрее.

EDIT: Это, кажется, не так просто, как казалось на первый взгляд. Как UIImage не соответствует NSCoding, клетки с настроенным UIImageViews не могут быть просто скопированы без дополнительного кода. Да, копирование всего изображения, безусловно, не является хорошей практикой, веселит к Apple, за указание на это.

Ответил 17/03/2011 в 13:00
источник пользователем

голоса
6

Используйте клонирование клеток, встроенное в виде таблицы. Apple, знал, генерируя много ячеек таблицы медленно. Проверьте документы для этого метода:

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

Вы создаете ячейку один раз, а затем, как новые клетки предлагается использовать этот метод, чтобы клонировать существующие клетки. Тогда вы просто изменить то, что должно быть изменено о новой ячейке и возвращает объект клеток.

Также проверьте вид таблицы realted образец код, предоставленный компании Apple, которая использует этот метод и показать вам правильный путь. Тот факт, ваша клетка была загружена из кончика пера не имеет значения.


Незначительное уточнение: я не думаю, что описанный выше способ клонировать клетки для вас. Вместо этого он принимает объект ячейки, которые прокручиваются с экрана и просто перемещает их на новое место. Так что буквально повторно использовать ячейку. Поэтому убедитесь, что ваш пользовательский вид таблицы может быть установлен на все новые значения, которые нужны за пределами intialization.

Ответил 20/02/2009 в 22:11
источник пользователем

голоса
4

Не горжусь этим решением, но она работает с максимальным числом возможных привязок IB:

Интерфейс (AlbumTableViewCell подкласс UITableViewCell которого экземпляр определяется в файле XIB AlbumViewController в):

@interface AlbumsViewController : UITableViewController {
    IBOutlet AlbumTableViewCell *tableViewCellTrack;
}

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack;

Реализация (разархивировать / архив делает копию / клонов вид ячейки таблицы):

@implementation AlbumsViewController

@synthesize tableViewCellTrack;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AlbumTableViewCell *cell = (AlbumTableViewCell *)[tableView dequeueReusableCellWithIdentifier: @"AlbumCell"];

    if (cell == nil) {
        AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease];
        [[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil];

        cell = albumsViewController.tableViewCellTrack;
    }

    cell.labelTitle.text = ...;
    cell.labelArtist.text = ...;

    return cell;
}
Ответил 08/12/2009 в 10:06
источник пользователем

голоса
3

Ну, я не знаю, почему все учебники вне там не указать этот шаг.

При использовании собственных пользовательских UITableViewCell от СИБ, называя dequeueReusableCellWithIdentifier не достаточно. Вы должны указать «идентификатор» в IB, только для для него в таблице с вкладкой Cell раздела.

Затем убедитесь, что идентификатор вы кладете в IB является таким же, как идентификатор используемого для dequeueReusableCellWithIdentifier.

Ответил 17/06/2009 в 05:10
источник пользователем

голоса
1

Здесь в Swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell : UITableViewCell?
    let cellId = String(format: "Cell%d", indexPath.row)
    cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?

    if cell == nil {
        let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
        cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
    }

    // do some stuff

    return cell!
}
Ответил 24/10/2015 в 02:00
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more