Как загрузить пользовательские UITableViewCells из файлов Xib? - PullRequest
288 голосов
/ 12 февраля 2009

Вопрос прост: как загрузить пользовательские UITableViewCell из файлов Xib? Это позволяет вам использовать Interface Builder для проектирования ваших ячеек. Ответ очевидно не прост из-за проблем управления памятью. В этой теме упоминается проблема и предлагается решение, но она выпущена до выпуска NDA и не содержит кода. Вот длинная нить , в которой обсуждается проблема без однозначного ответа.

Вот код, который я использовал:

static NSString *CellIdentifier = @"MyCellIdentifier";

MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
    cell = (MyCell *)[nib objectAtIndex:0];
}

Чтобы использовать этот код, создайте MyCell.m / .h, новый подкласс UITableViewCell и добавьте IBOutlets для компонентов, которые вы хотите. Затем создайте новый файл «Пустой XIB». Откройте файл Xib в IB, добавьте объект UITableViewCell, установите для его идентификатора значение «MyCellIdentifier», установите для его класса значение MyCell и добавьте свои компоненты. Наконец, подключите IBOutlets к компонентам. Обратите внимание, что мы не установили владельца файла в IB.

Другие методы рекомендуют устанавливать владельца файла и предупреждать об утечках памяти, если Xib не загружается через дополнительный фабричный класс. Я проверил вышеизложенное в разделе «Инструменты / утечки» и не обнаружил утечек памяти.

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

Ответы [ 23 ]

0 голосов
/ 18 мая 2018
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cellReuseIdentifier = "collabCell"
            var cell:collabCell! = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? collabCell
            if cell == nil {
                tableView.register(UINib(nibName: "collabCell", bundle: nil), forCellReuseIdentifier: cellReuseIdentifier)
                cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! collabCell!
            }


            return cell

}
0 голосов
/ 11 июня 2014
 NSString *CellIdentifier = [NSString stringWithFormat:@"cell %ld %ld",(long)indexPath.row,(long)indexPath.section];


    NewsFeedCell *cell = (NewsFeedCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell=nil;

    if (cell == nil)
    {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsFeedCell" owner:nil options:nil];

        for(id currentObject in topLevelObjects)
        {
            if([currentObject isKindOfClass:[NewsFeedCell class]])
            {
                cell = (NewsFeedCell *)currentObject;
                break;
            }
        }
}
return cell;
0 голосов
/ 28 августа 2015

Для этого расширения требуется Xcode7 beta6

extension NSBundle {
    enum LoadViewError: ErrorType {
        case ExpectedXibToExistButGotNil
        case ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
        case XibReturnedWrongType
    }

    func loadView<T>(name: String) throws -> T {
        let topLevelObjects: [AnyObject]! = loadNibNamed(name, owner: self, options: nil)
        if topLevelObjects == nil {
            throw LoadViewError.ExpectedXibToExistButGotNil
        }
        if topLevelObjects.count != 1 {
            throw LoadViewError.ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
        }
        let firstObject: AnyObject! = topLevelObjects.first
        guard let result = firstObject as? T else {
            throw LoadViewError.XibReturnedWrongType
        }
        return result
    }
}

Создайте Xib-файл, содержащий только 1 пользовательский UITableViewCell.

Загрузите его.

let cell: BacteriaCell = try NSBundle.mainBundle().loadView("BacteriaCell")
...