在UITableViewCell
中实施自定义tableView:cellForRowAtIndexPath:
时,这两种方式之间存在差异
loadNibNamed:owner:options:
和
SimpleTableCell *cell = [[SimpleTableCell alloc]init];
loadNibNamed:owner:options:
也是alloc init
吗?如果没有SimpleTableCell
,alloc init
将如何运作?
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
没有显式调用SimpleTableCell *cell = [[SimpleTableCell alloc]init];
答案 0 :(得分:2)
好的,首先关闭。我根本不会回答这个问题。相反,我将告诉您如何创建和使用自定义UITableViewCell
子类。你现在正在做的事情是对的。
让我们坚持您使用的名称SimpleTableCell
。
创建子类
创建UITableViewCell
。
SimpleTableCell.h
@interface SimpleTableCell : UITableViewCell
// if coding only
@property (nonatomic, strong) UILabel *simpleLabel
// if from nib
@property (nonatomic, weak) IBOutlet UILabel *simpleLabel;
@end
SimpleTableCell.m
#import "SimpleTableCell.h"
@implementation SimpleTableCell
// if coding only
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//create the simpleLabel and add to self.contentView
}
return self;
}
// if from nib no need to do anything at all
// other stuff...
- (void)prepareForReuse
{
// empty the cell here.
// means you don't have to empty everything out in the controller
self.simpleLabel.text = @"";
}
@end
好的,现在我们有一个细胞类。
创建NIB,如果这是您想要的
看起来你已经这样做了。
创建具有相同名称的笔尖(或不是,并不重要)。
将顶级项目设为UITableViewCell
并将子类设置为SimpleTableCell
。现在连接插座。在此示例中,simpleLabel
就是要连接的所有内容。
使用表格视图注册子类
在拥有表视图的视图控制器中。这意味着表格视图可以处理单元格的创建和出列,您根本不必手动创建它们。
- (void)viewDidLoad
{
[super viewDidLoad];
// set up the other stuff...
// if coding only
[self.tableView registerClass:[SimpleTableCell class] forCellReuseIdentifier:@"SimpleCell"];
// if from a nib
UINib *cellNib = [UINib nibWithNibName:@"SimpleTableCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:@"SimpleCell"];
}
现在,您只需让表格处理创建单元格。它跟踪重用标识符和单元队列,以便它可以正常处理所有内容。您只需要让它使用您为其注册子类的标识符为您出列单元格。
- (UITableViewCell*)tableView:(UITableView *)tableView cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
// This API was introduced in iOS6 and will ALWAYS return a valid cell.
// However, you need to register the class or nib with the table first.
// This is what we did in viewDidLoad.
// If you use a storyboard or nib to create a tableview and cell then this works too.
SimpleTableCell *mySimpleCell = [tableView dequeueReusableCellWithIdentifier:@"SimpleCell" forIndexPath:indexPath];
mySimpleCell.simpleLabel.text = @"Hello, World";
return mySimpleCell;
}
修改强>
您可以使用...
创建一个单元格(实际上是任何类)SimpleTableCell *cell = [[SimpleTableCell alloc] init];
但这样做意味着它没有与表视图或队列的一部分相关联。
从我的答案中的方法向下一步(如果你愿意)是使用旧的dequeuReusableCell...
方法,然后检查它是否为零,并按照这样创建它......
- (UITableViewCell*)tableView:(UITableView *)tableView cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
// Old way, don't do this if you're targeting iOS6.0+
SimpleTableCell *mySimpleCell = [tableView dequeueReusableCellWithIdentifier:@"SimpleCell"];
if (!mySimpleCell) {
// have to use initWithStyle:reuseIdentifier: for the tableView to be able to dequeue
mySimpleCell = [[SimpleTableCell alloc] initWithStyle:UITableViewCellStyleCustom reuseIdentifier:@"SimpleCell"];
}
mySimpleCell.simpleLabel.text = @"Hello, World";
return mySimpleCell;
}
我甚至不确定你是否可以从这里的笔尖加载,因为你无法在单元格上设置重用标识符。
多个细胞亚类
好的,上次编辑:D
对于多个UITableViewCell
子类,您也可以使用它。我过去做过这个。例如,您可能有一个Post
项的单元格,Image
项目的单元格,Comment
项目的单元格等等......它们都是不同的。
因此...
- (void)viewDidLoad
{
// the rest
// register each subclass with a different identifier
[self.tableView registerClass:[PostCell class] forCellReuseIdentifier:@"PostCell"];
[self.tableView registerClass:[ImageCell class] forCellReuseIdentifier:@"ImageCell"];
[self.tableView registerClass:[CommentCell class] forCellReuseIdentifier:@"CommentCell"];
}
为了帮助保持这个小(并且它对NSFetchedResultsControllers也很方便,我将单元格的配置移到另一个方法。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if (the required cell is a post cell) {
cell = [tableView dequeueReusableCellWithIdentifier:@"PostCell" forIndexPath:indexPath];
[self configurePostCell:(PostCell *)cell atIndexPath:indexPath];
} else if (the required cell is a image cell) {
cell = [tableView dequeueReusableCellWithIdentifier:@"ImageCell" forIndexPath:indexPath];
[self configureImageCell:(ImageCell *)cell atIndexPath:indexPath];
} else if (the required cell is a comment cell) {
cell = [tableView dequeueReusableCellWithIdentifier:@"CommentCell" forIndexPath:indexPath];
[self configureCommentCell:(CommentCell *)cell atIndexPath:indexPath];
}
return cell;
}
- (void)configurePostCell:(PostCell *)postCell atIndexPath:(NSIndexPath *)indexPath
{
// get the object to be displayed...
postCell.postLabel = @"This is the post text";
postCell.dateLabel = @"5 minutes ago";
}
- (void)configureImageCell:(ImageCell *)imageCell atIndexPath:(NSIndexPath *)indexPath
{
// get the object to be displayed...
imageCell.theImageView.image = //the image
imageCell.dateLabel = @"5 minutes ago";
}
- (void)configureCommentCell:(CommentCell *)commentCell atIndexPath:(NSIndexPath *)indexPath
{
// you get the picture...
}
答案 1 :(得分:0)
loadNibNmed:...
要求系统从nib文件中的固定实例重新创建一个对象(通常但不限于UIView)。使用Xcode的界面构建器部分创建nib文件。
当从nib文件加载对象时loadNibNamed...
)init
没有被调用,而是调用initWithCoder:
。如果您要在从nib文件加载的视图上进行后初始化设置,通常的方法是awakeFromNib
并调用[super awakeFromNib]