问题很简单:如何从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加载单元格的规范方法是什么呢?我们设置文件的所有者吗?我们需要工厂吗?如果是,工厂的代码是什么样子的?如果有多种解决方案,让我们来阐明每一种方案的优缺点。
为此,我在控制器类中声明了一个IBOutlet UITableViewCell *单元格。
然后调用NSBundle loadNibNamed类方法,它将把UITableViewCell提供给上面声明的单元格。
对于xib,我将创建一个空的xib,并在IB中添加UITableViewCell对象,它可以根据需要进行设置。然后,该视图连接到控制器类中的单元IBOutlet。
- (UITableViewCell *)tableView:(UITableView *)table
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%@ loading RTEditableCell.xib", [self description] );
static NSString *MyIdentifier = @"editableCellIdentifier";
cell = [table dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"RTEditableCell"
owner:self
options:nil];
}
return cell;
}
NSBundle添加loadNibNamed (ADC登录)
cocoawithlove.com文章我的概念来源(获取电话号码示例应用程序)
把肖恩·克雷弗的答案整理了一下。
BBCell.h:
#import <UIKit/UIKit.h>
@interface BBCell : UITableViewCell {
}
+ (BBCell *)cellFromNibNamed:(NSString *)nibName;
@end
BBCell.m:
#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"];
我决定发帖,因为我不喜欢这些答案——事情总是可以更简单,这是迄今为止我发现的最简洁的方法。
1. 在接口生成器中构建你的Xib,因为你喜欢它
将File's Owner设置为类NSObject
添加一个UITableViewCell,并将它的类设置为MyTableViewCellSubclass——如果你的IB崩溃(在Xcode > 4中发生),只要在Xcode 4中使用一个UIView来做接口,如果你仍然有它在周围
在这个单元格中布局子视图,并将IBOutlet连接以.h或.m(。M是我的首选)
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.在你的mytableviewcell子类中
- (id) initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
...
}
return self;
}