UITableViewCell 的初始化在哪里?
Posted
技术标签:
【中文标题】UITableViewCell 的初始化在哪里?【英文标题】:Where are the UITableViewCell's initialized? 【发布时间】:2014-02-13 19:52:15 【问题描述】:我创建了自己的CustomTableView
和CustomCell
。单元格在xib
中,我在初始化tableView 时正在注册它,如下所示:
[self registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil]
forCellReuseIdentifier:kCustomCellIdentifier];
如果我不这样做,我将无法定义 ReuseIdentifier
应该“指向”这个类的内容。这是我的cellForRow
:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
CustomCell *cell = [self dequeueReusableCellWithIdentifier:
kCustomCellIdentifier forIndexPath:indexPath];
if(!cell)
cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell"
owner:self options:nil] objectAtIndex:0];
cell.delegate = self;
[cell initialSetup]; //Other stuff
else
[cell resetCell];
//And other awesome stuff
return cell;
这“有效”。当我启动我的应用程序时,我自己的自定义单元格正在显示。
然而,事实证明该单元格从未从[self dequeue..
返回为nil
。因此,if 语句if(!cell)
永远不会为真。我在这个语句中有额外的设置,我想执行,但我不知道现在第一次初始化单元格的位置。如果我删除registerNib
,那么这个陈述是正确的,但是对于所有单元格都是正确的,并且不会被出列。
我可能可以解决这个问题,并将我的initialSetup
(和其他东西)放在 CustomCell 类的-(id)initWithCoder..
-方法中,但我想知道我的单元格现在在哪里被初始化。为什么我的单元格在cellForRowAtIndexPath
之前存在?
【问题讨论】:
你在使用storyboard
吗?
那么if(!cell)
将不成立,因为dequeueReusableCellWithIdentifier
返回一个单元格。在CustomCell
中使用awakeFromNib
方法
@Akhilrajtr 但dequeue..
的意义不在于我在重复使用自己的细胞吗?我想象的方式是,在发布时 - 没有单元格已排队。我从来没有做过,所以他们怎么会排队,对吧?然后,当我向下滚动 10 行时,我创建的第一个单元格将被排队而不是被释放,以便我以后可以使用它。当我需要第 11 个单元格时,它首先通过调用dequeueReusable..
来检查这个队列。由于我的第一个单元格已排队,因此将在此处返回。这对我来说很有意义。如果你们说dequeue
总是返回一个单元格,那我什么都不懂。
我看到的所有例子都把if(!cell)
放在dequeueReusableCell..
之后。另外,使用awakeFromNib
而不是-initWithCoder
对我来说有什么区别?
覆盖prepareForReuse
的UITableViewCell
方法
【参考方案1】:
当您使用方法registerClass:forCellReuseIdentifier
或registerNib:forCellReuseIdentifier
在表格视图中注册一个类或nib时,如果您调用dequeueReusableCellWithIdentifier:
时没有可用的单元格,则表格视图内部将创建一个单元格的实例,因此初始化代码是委托内部不再需要。
来自UITableView.h
代码:
// Beginning in ios 6, clients can register a nib or class for each cell.
// If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.
// Instances returned from the new dequeue method will also be properly sized when they are returned.
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
根据使用的register
方法,调用的init
方法有:
initWithStyle:reuseIdentifier
用于使用 registerClass:
注册的单元格
initWithCoder:
用于使用 registerNib:
注册的单元格
如果您使用registerNib:
,您也可以在单元格中使用awakeFromNib
方法,这也是放置单元格初始化代码的好地方。使用initWithCoder:
或awakeFromNib
的主要区别在this question 中进行了说明。
当一个单元格被重用时,您可以在单元格中使用prepareForReuse
方法对单元格进行一些清理,并使其准备好再次配置。
处理所有这些的好方法是:
//ViewController code
- (void)viewDidLoad
...
[_tableView registerNib:[UINib nibWithNibName:@"CellSample" bundle:Nil] forCellReuseIdentifier:@"cellIdentifier"];
...
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
//configure the new cell, no if (!cell) needed
return cell;
//Cell code
- (id)initWithCoder:(NSCoder *)aDecoder
self = [super initWithCoder:aDecoder];
if (self)
//You can put initialization here
return self;
- (void)awakeFromNib
[super awakeFromNib];
//But is better initialize here
- (void)prepareForReuse
//Reuse and reset the cell here
希望对你有帮助
【讨论】:
【参考方案2】:使用dequeueReusableCellWithIdentifier: forIndexPath:
时,您不必像使用默认UITableViewCell
那样分配单元格。在您的自定义 UITableViewCell
子类中,它在初始化时被调用:
- (void)awakeFromNib
[super awakeFromNib];
所以把它加进去,你应该会很好。
【讨论】:
【参考方案3】:- (instancetype)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
//custom your cell
return self;
【讨论】:
除了代码之外,通常最好提供一些关于原因或如何回答问题的解释。以上是关于UITableViewCell 的初始化在哪里?的主要内容,如果未能解决你的问题,请参考以下文章
无法与 UITableViewCell 中的任何内容进行交互,我在某处被布尔值阻塞,它在哪里?
在哪里编写方法drawRect:iPhone SDK中的UIViewController和UITableViewCell
Xcode interface Builder 没有给我选择在哪里放置 UITableViewCell 的重用标识符
如何在 UITableViewCell 上使用自定义初始化程序?