问题很简单:如何从Xib文件加载自定义UITableViewCell ?这样做允许您使用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的一个新子类,并为您想要的组件添加iboutlet。然后创建一个新的“Empty XIB”文件。在IB中打开Xib文件,添加一个UITableViewCell对象,将其标识符设置为“MyCellIdentifier”,并将其类设置为MyCell并添加组件。最后,将iboutlet连接到组件。注意,我们没有在IB中设置文件的所有者。

其他方法主张设置文件的所有者,如果Xib没有通过额外的工厂类加载,则警告内存泄漏。我在Instruments/Leaks下测试了上面的内容,没有发现内存泄漏。

那么从xib加载单元格的规范方法是什么呢?我们设置文件的所有者吗?我们需要工厂吗?如果是,工厂的代码是什么样子的?如果有多种解决方案,让我们来阐明每一种方案的优缺点。


当前回答

从UITableViewCell创建自己的自定义类AbcViewCell子类(确保你的类文件名和nib文件名是相同的) 创建这个扩展类方法。 扩展UITableViewCell { class func fromNib<T: UITableViewCell>() -> T { Bundle.main返回。loadNibNamed(字符串(描述:T.self),所有者:nil,选项:nil)?[0]一样!T } } 使用它。 let cell: AbcViewCell = UITableViewCell.fromNib()

其他回答

下面是我一直用于从xib中创建自定义单元格的类方法:

+ (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]更可靠,至少在我看来,比Stephan Burlot的示例更可靠,因为可以保证只从正确类型的XIB中获取视图。

正确的方法是创建一个UITableViewCell子类实现、header和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;
}

检查这个- http://eppz.eu/blog/custom-uitableview-cell/ -非常方便的方式使用一个小类,在控制器实现中结束一行:

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

下面是我的方法:从XIB文件加载自定义UITableViewCells

这个想法是创建一个UITableViewCell的SampleCell子类,它带有一个IBOutlet UIView *content属性和一个用于您需要从代码中配置的每个自定义子视图的属性。然后创建一个SampleCell。xib文件。在这个nib文件中,将文件所有者更改为SampleCell。添加一个内容UIView大小,以适应您的需要。添加和配置你想要的所有子视图(标签、图像视图、按钮等)。最后,将内容视图和子视图链接到文件所有者。

首先导入你的自定义单元格文件#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;
}