Как вы загружаете пользовательские UITableViewCells из файлов Xib?



вопрос прост: как вы загружаете custom 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.м./h, новый подкласс UITableViewCell и добавить IBOutlets для тех компонентов, которые вы хотите. Затем создайте новый "пустой XIB" файл. Откройте файл Xib в IB, добавьте a UITableViewCell объект, установите его идентификатор в "MyCellIdentifier", а его класс В MyCell и добавьте свои компоненты. Наконец, подключите IBOutlets к компонентам. Обратите внимание, что мы не установили владельца файла в IB.



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



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

636   22  

22 ответов:

вот два метода, которые оригинальные авторские государства были рекомендованы инженером IB.

см. фактический пост для получения более подробной информации. Я предпочитаю Метод №2, как это кажется проще.

Способ #1:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Create a temporary UIViewController to instantiate the custom cell.
        UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"BDCustomCell" bundle:nil];
        // Grab a pointer to the custom cell.
        cell = (BDCustomCell *)temporaryController.view;
        [[cell retain] autorelease];
        // Release the temporary UIViewController.
        [temporaryController release];
    }

    return cell;
}

Способ № 2:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = [topLevelObjects objectAtIndex:0];
    }

    return cell;
}

обновление (2014): Метод №2 все еще действителен, но для него больше нет документации. Раньше он был в официальные документы но теперь снимается в пользу раскадровки.

я опубликовал рабочий пример на Github:
https://github.com/bentford/NibTableCellExample

правильное решение это:

- (void)viewDidLoad
{
 [super viewDidLoad];
 UINib *nib = [UINib nibWithNibName:@"ItemCell" bundle:nil];
 [[self tableView] registerNib:nib forCellReuseIdentifier:@"ItemCell"];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   // Create an instance of ItemCell
   PointsItemCell *cell =  [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];

return cell;
}

зарегистрироваться

после iOS 7, этот процесс был упрощен до (swift 3.0):

// For registering nib files
tableView.register(UINib(nibName: "MyCell", bundle: Bundle.main), forCellReuseIdentifier: "cell")

// For registering classes
tableView.register(MyCellClass.self, forCellReuseIdentifier: "cell")

(Примечание) это также достижимо путем создания ячеек в .xib или .stroyboard файлы, как прототип клеток. Если вам нужно прикрепить к ним класс, вы можете выбрать прототип ячейки и добавить соответствующий класс (должен быть потомком UITableViewCell, of курс.)

Dequeue

и позже, в очереди с помощью (swift 3.0):

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = "Hello"

    return cell
}

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

(предупреждение)tableView.dequeueReusableCell(withIdentifier:for:) имеет новое поведение, если вы позвоните в другой (без indexPath:) вы получаете старое поведение, в котором вам нужно проверить nil и пример его сам, обратите внимание на UITableViewCell? возвращаемое значение.

if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? MyCellClass
{
    // Cell be casted properly
    cell.myCustomProperty = true
}
else
{
    // Wrong type? Wrong identifier?
}

и, конечно же, тип связанного класса ячейки-это тот, который вы определили в .xib файл для UITableViewCell подкласс, или альтернативно, используя другой способ регистрации.

конфигурация

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

все вместе

class MyCell : UITableViewCell
{
    // Can be either created manually, or loaded from a nib with prototypes
    @IBOutlet weak var labelSomething : UILabel? = nil
}

class MasterViewController: UITableViewController 
{
    var data = ["Hello", "World", "Kinda", "Cliche", "Though"]

    // Register
    override func viewDidLoad()
    {
        super.viewDidLoad()

        tableView.register(MyCell.self, forCellReuseIdentifier: "mycell")
        // or the nib alternative
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return data.count
    }

    // Dequeue
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for: indexPath) as! MyCell

        cell.labelSomething?.text = data[indexPath.row]

        return cell
    }
}

и, конечно же, все это доступно в ObjC с теми же именами.

взял ответ Шона Крейвера и немного очистил его.

BBCell.h:

#import <UIKit/UIKit.h>

@interface BBCell : UITableViewCell {
}

+ (BBCell *)cellFromNibNamed:(NSString *)nibName;

@end

BBCell.м:

#import "BBCell.h"

@implementation BBCell

+ (BBCell *)cellFromNibNamed:(NSString *)nibName {
    NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:NULL];
    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    BBCell *customCell = nil;
    NSObject* nibItem = nil;
    while ((nibItem = [nibEnumerator nextObject]) != nil) {
        if ([nibItem isKindOfClass:[BBCell class]]) {
            customCell = (BBCell *)nibItem;
            break; // we have a winner
        }
    }
    return customCell;
}

@end

Я делаю все мои UITableViewCell подклассы BBCell, а затем заменить стандартный

cell = [[[BBDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BBDetailCell"] autorelease];

С:

cell = (BBDetailCell *)[BBDetailCell cellFromNibNamed:@"BBDetailCell"];

я bentford это Способ #2:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = [topLevelObjects objectAtIndex:0];
    }

    return cell;
}

это работает, но следите за подключениями к файла в вашем пользовательском UITableViewCell .файл xib.

, передав owner:self в своем loadNibNamed заявление, вы выберите UITableViewController как владелец файла вашего UITableViewCell.

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

In loadNibNamed:owner:options, код Apple будет пытаться установить свойства на вашем UITableViewController, так как это владелец. Но у вас нет этих свойств, определенных там, поэтому вы получаете сообщение об ошибкеключа кодирования-совместимый стоимостью:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason:     '[<MyUITableViewController 0x6a383b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myLabel.'

если вместо этого запускается событие, вы получите исключение NSInvalidArgumentException:

-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0'
*** First throw call stack:
(0x1903052 0x15eed0a 0x1904ced 0x1869f00 0x1869ce2 0x1904ec9 0x5885c2 0x58855a 0x62db76 0x62e03f 0x77fa6c 0x24e86d 0x18d7966 0x18d7407 0x183a7c0 0x1839db4 0x1839ccb 0x1f8b879 0x1f8b93e 0x585a9b 0xb904d 0x2c75)
terminate called throwing an exceptionCurrent language:  auto; currently objective-c

простой обходной путь-указать ваши соединения с построителем интерфейса на UITableViewCell вместо файла Владелец:

  1. щелкните правой кнопкой мыши на владельце файла, чтобы открыть список соединений
  2. сделайте снимок экрана с помощью Command-Shift-4 (перетащите, чтобы выбрать область для захвата)
  3. x из соединений от владельца файла
  4. щелкните правой кнопкой мыши на ячейке UITableCell в иерархии объектов и повторно добавьте соединения.

Я решил опубликовать, так как мне не нравится ни один из этих ответов-вещи всегда могут быть более простыми, и это, безусловно, самый краткий способ, который я нашел.

1. Создайте свой Xib в Interface Builder, как вам нравится

  • установить владельца файла в класс NSObject
  • добавьте UITableViewCell и установите его класс В MyTableViewCellSubclass -- если ваш IB аварийно завершает работу (происходит в Xcode > 4 на момент написания этой статьи), просто используйте UIView do the interface in Xcode 4, если он все еще лежит вокруг
  • расположите свои подвиды внутри этой ячейки и прикрепите свои соединения IBOutlet к своему @интерфейсу .ч или .м.( м-это мое предпочтение)

2. В вашем подклассе UIViewController или UITableViewController

@implementation ViewController

static NSString *cellIdentifier = @"MyCellIdentier";

- (void) viewDidLoad {

    ...
    [self.tableView registerNib:[UINib nibWithNibName:@"MyTableViewCellSubclass" bundle:nil] forCellReuseIdentifier:cellIdentifier];
}

- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyTableViewCellSubclass *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    ...

    return cell;
}

3. В вашем MyTableViewCellSubclass

- (id) initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        ...
    }

    return self;
}

Если вы используете Interface Builder для создания ячеек, проверьте, что вы установили идентификатор в Инспекторе. Затем проверьте, что это то же самое при вызове dequeueReusableCellWithIdentifier.

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

загрузка UITableViewCells из XIBs экономит много кода, но обычно приводит к ужасной скорости прокрутки (на самом деле, это не XIB, а чрезмерное использование UIViews, которые вызывают это).

Я предлагаю вам взглянуть на это: Ссылка Ссылка

вот метод класса, который я использую для создания пользовательских ячеек из XIBs:

+ (CustomCell*) createNewCustomCellFromNib {

    NSArray* nibContents = [[NSBundle mainBundle]
                            loadNibNamed:@"CustomCell" owner:self options:NULL];

    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    CustomCell *customCell= nil;
    NSObject* nibItem = nil;

    while ( (nibItem = [nibEnumerator nextObject]) != nil) {

        if ( [nibItem isKindOfClass: [CustomCell class]]) {
            customCell = (CustomCell*) nibItem;

            if ([customCell.reuseIdentifier isEqualToString: @"CustomCell"]) {
                break; // we have a winner
            }
            else
                fuelEntryCell = nil;
        }
    }
    return customCell;
}

затем в XIB я устанавливаю имя класса и идентификатор повторного использования. После этого я могу просто вызвать этот метод в моем контроллере вида вместо

[[UITableViewCell] alloc] initWithFrame:]

Это достаточно быстро, и используется в двух моих судоходства. Это надежнее, чем звонить [nib objectAtIndex:0], и на мой взгляд, по крайней мере, более надежный, чем пример Стефана Берло, потому что вы гарантируется только захват вида из XIB, который является правильным типом.

правильное решение это

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomCell"];
}

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

перезагрузка наконечника стоит дорого. Лучше загрузить его один раз, а затем создать экземпляр объектов, когда вам нужна ячейка. Обратите внимание, что вы можете добавить UIImageViews etc к nib, даже несколько ячеек, используя этот метод (Apple "registerNIB" iOS5 позволяет только один объект верхнего уровня-ошибка 10580062 "iOS5 tableView registerNib: чрезмерно ограничительный"

Итак, мой код ниже-Вы читаете в NIB один раз (в initialize, как я сделал, или в viewDidload - что угодно. С этого момента вы создаете экземпляр пера в затем выберите объекты, которые вам нужны. Это гораздо эффективнее, чем загружать перо снова и снова.

static UINib *cellNib;

+ (void)initialize
{
    if(self == [ImageManager class]) {
        cellNib = [UINib nibWithNibName:@"ImageManagerCell" bundle:nil];
        assert(cellNib);
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"TheCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if(cell == nil) {
        NSArray *topLevelItems = [cellNib instantiateWithOwner:nil options:nil];
        NSUInteger idx = [topLevelItems indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
                            {
                                UITableViewCell *cell = (UITableViewCell *)obj;
                                return [cell isKindOfClass:[UITableViewCell class]] && [cell.reuseIdentifier isEqualToString:cellID];
                            } ];
        assert(idx != NSNotFound);
        cell = [topLevelItems objectAtIndex:idx];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"Howdie %d", indexPath.row];

    return cell;
}

проверьте это -http://eppz.eu/blog/custom-uitableview-cell/ - действительно удобный способ использования крошечного класса, который заканчивается одной строкой в реализации контроллера:

-(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
    return [TCItemCell cellForTableView:tableView
                          atIndexPath:indexPath
                      withModelSource:self];
}

enter image description here

правильный способ сделать это-создать реализацию подкласса UITableViewCell, заголовок и XIB. В XIB удалите все представления и просто добавьте ячейку таблицы. Установите класс в качестве имени подкласса UITableViewCell. Для владельца файла сделайте его именем класса подкласса UITableViewController. Подключите владельца файла к ячейке с помощью розетки tableViewCell.

в заголовочном файле:

UITableViewCell *_tableViewCell;
@property (assign) IBOutlet UITableViewCell *tableViewCell;

в файле реализации:

@synthesize tableViewCell = _tableViewCell;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *kCellIdentifier = @"reusableCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:kCellIdentifier owner:self options:nil];
        cell = _tableViewCell;
        self.tableViewCell = nil;
    }

    return cell;
}

то, что я делаю для этого, объявляет IBOutlet UITableViewCell *cell в своем классе контроллера. Затем вызовите NSBundle loadNibNamed метод класса, который будет кормить UITableViewCell к ячейке, объявленной выше.

для xib я создам пустой xib и добавить

сначала импортируйте свой собственный файл ячейки #import "CustomCell.h" а затем измените метод делегата, как указано ниже:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *simpleTableIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}         

     return cell;
}
  1. создайте свой собственный настроенный класс AbcViewCell подкласс от UITableViewCell (убедитесь, что имя файла класса и имя файла nib совпадают)

  2. создайте этот метод класса расширения.

    extension UITableViewCell {
        class func fromNib<T : UITableViewCell>() -> T {
            return Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)?[0] as! T
        }
    }
    
  3. использовать его.

    let cell: AbcViewCell = UITableViewCell.fromNib()

Я не знаю, есть ли канонический способ, но вот мой метод:

  • создать xib для ViewController
  • установите класс владельца файла в UIViewController
  • удалите представление и добавьте UITableViewCell
  • установите класс вашего UITableViewCell в свой пользовательский класс
  • установите идентификатор вашего UITableViewCell
  • установите выход вашего взгляда регулятора взгляда к вашему UITableViewCell

и используйте этот код:

MyCustomViewCell *cell = (MyCustomViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
  UIViewController* c = [[UIViewController alloc] initWithNibName:CellIdentifier bundle:nil];
  cell = (MyCustomViewCell *)c.view;
  [c release];
}

в вашем примере, используя

[nib objectAtIndex:0]

может сломаться, если Apple изменит порядок элементов в xib.

вот мой метод для этого:загрузка пользовательских UITableViewCells из XIB файлов ... еще один метод

идея состоит в том, чтобы создать подкласс SampleCell UITableViewCell с IBOutlet UIView *content свойство и свойство для каждого пользовательского подвида, которое необходимо настроить из кода. Затем создать ячейку выборки.файл xib. В этом файле nib измените владельца файла на SampleCell. Добавить контент UIView размер в соответствии с вашими потребностями. Добавление и настройка всех вложенных представлений (меток, изображений, кнопки и т. д.) Вы хотите. Наконец, свяжите представление содержимого и вложенные представления с владельцем файла.

 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;

Это расширение требует 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")

вот универсальный подход для регистрации ячеек в UITableView:

protocol Reusable {
    static var reuseID: String { get }
}

extension Reusable {
    static var reuseID: String {
        return String(describing: self)
    }
}

extension UITableViewCell: Reusable { }

extension UITableView {

func register<T: UITableViewCell>(cellClass: T.Type = T.self) {
    let bundle = Bundle(for: cellClass.self)
    if bundle.path(forResource: cellClass.reuseID, ofType: "nib") != nil {
        let nib = UINib(nibName: cellClass.reuseID, bundle: bundle)
        register(nib, forCellReuseIdentifier: cellClass.reuseID)
    } else {
        register(cellClass.self, forCellReuseIdentifier: cellClass.reuseID)
    }
}

объяснение:

  1. Reusable протокол генерирует идентификатор ячейки из ее имени класса. Убедитесь, что вы следуете конвенции:cell ID == class name == nib name.
  2. UITableViewCell соответствует Reusable протокол.
  3. UITableView расширение абстрагирует разницу в регистрации ячеек через перо или класс.

пример использования:

override func viewDidLoad() {
    super.viewDidLoad()
    let tableView = UITableView()
    let cellClasses: [UITableViewCell.Type] = [PostCell.self, ProfileCell.self, CommentCell.self]
    cellClasses.forEach(tableView.register)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: PostCell.self.reuseID) as? PostCell
    ...
    return cell
}
 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

}

Comments

    Ничего не найдено.