iOS:DequeTableViewCell ..有点困惑

时间:2013-06-07 08:30:11

标签: ios tableview

我想改变UITableView单元格的字体大小和颜色等。我在Xcode中设计了自定义单元格,并使一切正常。

首先我会在这里发布我的代码: UITableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.tableView registerClass:MainCategoryTableViewCell.class forCellReuseIdentifier:@"MainCategoryCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"MainCategoryCell";
    MainCategoryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    return cell;
}

我的自定义单元格:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.title.font = [Theme tableCellTitleFont];
        self.title.textColor = [Theme tableCellTitleColor];

        self.subcategories.font = [Theme tableCellSubTitleFont];
        self.subcategories.textColor = [Theme tableCellSubTitleColor];

        self.costs.font = [Theme tableCellValueFont];
        self.costs.textColor = [Theme tableCellValueColor];
    }
    return self;
}

我现在很困惑这个出队的工作方式: 据我所知,如果我在viewDidLoad中注册该类,则只有单元的initWithStyle方法被调用,而没有单元可以重用。如果有一个单元用于重复使用它将被使用。我在其他代码片段中看到过很多if(cell == nil)调用,但这真的有必要吗?我认为registerClass方法无论如何都要处理这个问题?

此刻我的细胞将完全显示为空。在我注册课程之前一切正常,但initWithStyle没有被调用..

完成cellForRowAtIndexPathMethod

#pragma mark Delegate methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"MainCategoryCell";
    MainCategoryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    MainCategory *mainCategory = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.title.text = mainCategory.name;
    cell.subcategories.text = [NSString stringWithFormat:@"%i subcategories", [[mainCategory getNumberOfSpendingCategories] integerValue]];
    cell.costs.text = [[mainCategory getMonthlyCostsOfAllSpendingCategories] getLocalizedCurrencyString];
    if(!mainCategory.icon){
        cell.icon.image = [UIImage imageNamed:@"DefaultIcon.png"];
    } else {
        cell.icon.image = [UIImage imageNamed:mainCategory.icon];
    }

    if(!mainCategory.color){
        cell.backgroundColor = [PresetColor colorForPresetColor:PresetColorsWhite];
    } else {
        cell.backgroundColor = [PresetColor colorForPresetColor:(PresetColors)[mainCategory.color intValue]];
    }

    cell.cellBackground.image = [[UIImage imageNamed:@"content-bkg"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];

    return cell;
}

3 个答案:

答案 0 :(得分:3)

如果您已将单元格定义为xib / storyboard文件中表格视图的“原型单元格”,那么您根本不需要注册它。如果自定义单元格位于单独的nib文件中,则使用registerNib注册自定义单元格,而不是registerClass。例如:

[self.tableView registerNib:[UINib nibWithNibName:@"MainCategoryTableViewCell" bundle:nil]
      forCellReuseIdentifier:@"MainCategoryCell"];

对于从nib文件实例化的单元格,调用initWithCoder,而不是initWithStyle

要配置自定义单元格的任何插座,请覆盖awakeFromNib。连接是 尚未在initWithCoder中确定。

答案 1 :(得分:1)

为了便于理解,请参阅下面的图片以获取双连接参考。

Deque意味着您可以从两端添加和删除单元格。

结束时我的意思是上下。

假设你有4个细胞含有Acell,Bcell,Ccell和Dcell,行的高度是三个细胞。

所以一次只能看到3个细胞。

当你滚动查看Dcell时,Acell将变为不可见的行,并且它的内存将被重用于Dcell。

以同样的方式滚动查看Acell时,Dcell将变为不可见的行,并且它的内存将被重用于Acell。

Help

答案 2 :(得分:0)

它在文档中清楚地说明了

  

dequeueReusableCellWithIdentifier:forIndexPath:

     

出于性能原因,通常应该使用表视图的数据源   在将单元格分配给其中的行时,重用UITableViewCell对象   tableView:cellForRowAtIndexPath:方法。表视图维护一个   数据源具有的UITableViewCell对象的队列或列表   标记为重用。何时从数据源对象中调用此方法   要求为表格视图提供新单元格。该方法出列   现有单元格(如果有)或基于该单元格创建新单元格   您之前注册的类或nib文件。

  

dequeueReusableCellWithIdentifier:

     

返回值:具有关联标识符的UITableViewCell对象   如果可重用单元队列中不存在此类对象,则为nil。

     

讨论:出于性能原因,表视图的数据源   通常应该在分配单元格时重用UITableViewCell对象   到其tableView:cellForRowAtIndexPath:方法中的行。表格视图   维护数据的UITableViewCell对象的队列或列表   source标记为重用。从您的数据源调用此方法   当要求为表视图提供新单元格时对象。这个   如果现有单元格可用或创建新单元格,则该方法会将现有单元格取消   一个使用您先前注册的类或nib文件。如果没有细胞   是可以重用的,你没有注册一个类或nib文件,   这个方法返回nil。

     

如果您为指定的标识符和新单元格注册了一个类   必须创建,此方法通过调用它来初始化单元格   initWithStyle:reuseIdentifier:方法。对于基于笔尖的细胞,这个   方法从提供的nib文件加载单元格对象。如果   现有的单元可以重用,这种方法称为单元   而不是prepareForReuse方法。

在介绍storyboard之前。tableview检查返回的单元格,它可以是nil。所以如果没有,我们必须重新分配单元格并且tehn初始化并在数据源方法中提供单元格