【问题标题】:UITableViewCell - Best place to set up the cellUITableViewCell - 设置单元格的最佳位置
【发布时间】:2012-02-27 05:33:50
【问题描述】:

我一直在玩 UITableViewController 中的自定义单元格,有一个基本单元格(BaseCell - UITableViewCell 的子类),然后是 BaseCell 的子类(Sub1Cell,Sub2Cell,BaseCell 的两个子类)。

因为子类共享一些相同的功能,如果我将它们完全设置在

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

我开始为每种细胞类型重复代码。将通用设置代码放在实际的自定义 UITableViewCell 类中是否有一个好地方,并且是一个好习惯吗?目前我已经写了一个简单的设置方法:

- (void)setupCell
{
    self.picture.layer.cornerRadius = 5.0f;
    self.picture.layer.masksToBounds = YES;
    self.picture.layer.borderColor = [[UIColor lightGrayColor] CGColor];
    self.picture.layer.borderWidth = 1.0f;
}

创建单元格后,我一直在调用它:

Sub1Cell *cell = [tableView dequeueReusableCellWithIdentifier:statusCellIdentifier];
[cell setupCell];

有没有可以自动调用的方法?我尝试了 -(void) prepareForReuse,但显然不是每次都调用它,只有在重用单元格时才调用它。

对解决此问题的最佳方法有什么建议吗?

编辑:

似乎每次我打电话给tableView:cellForRowAtIndexPath时都会被调用。我对创建自定义单元格的正确方法有点困惑。我是否应该按照以下方式做一些事情:

Sub1Cell *cell = [tableview dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
    cell = [[Sub1Cell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    [cell setupCell];
}

如果我对传递的样式不做任何事情,它会影响我的自定义单元格吗?

【问题讨论】:

  • 您是在为单元格使用故事板(动态原型)或单独的 xib 文件,还是在代码中添加所有内容?
  • 一个带有动态原型的故事板,用于布置诸如 UILabel 和 UIImageViews 之类的东西,然后在代码中设置内容和其他设置。这是 iOS 5 的最佳方法吗?
  • 是的,完美。我已经在下面回答了。

标签: ios uitableview


【解决方案1】:

您可以在单元格子类中使用awakeFromNib。当从故事板中的原型创建新单元格时将调用此方法,但在重新使用单元格时不会调用。

如果您正在使用原型,那么整个 if (cell == nil) 事情就会消失,UITableView 会在 dequeue 方法中为您处理所有这些事情。

【讨论】:

  • 当我们讨论这个话题时,在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 和单元格的类之间是否有设置单元格的“最佳实践”?我想我会在单元格的类中设置 UI 属性等内容,但在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中设置实际内容。这听起来像是解决这个问题的好方法吗?另一种方法是向单元格本身添加一些数据(例如 NSDictionary),以便它可以用内容填充自己。
【解决方案2】:

在自定义cell类中,提供init方法,进行初始化。一些代码如下:

- (id)initWithReuseIdentifier:(NSString *)cellIdentifier
{
    if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier])
    {
        self.picture.layer.cornerRadius = 5.0f;
        self.picture.layer.masksToBounds = YES;
        self.picture.layer.borderColor = [[UIColor lightGrayColor] CGColor];
        self.picture.layer.borderWidth = 1.0f;
    }
    return self;
}

【讨论】:

  • 您似乎在 void 方法中有一个 return 语句:D
  • 这些方法的默认返回类型是 id。我会再次尝试这种方法。你知道将 UITableViewCellStyleDefault 传递给 super 的 init 是否会改变单元格的外观吗?
  • @ChristopherOldfield 单元格的外观完全由您自己控制。将您想要的任何视图添加到单元格的 contentView。在 BaseCell 类中定义此方法。此解决方案用于编程自定义表格单元格。
  • @WubaoLi :) (blablabla for comment length)
【解决方案3】:

看起来不错。只要您只在创建单元格时调用它,而不是在每次通过tableView:cellForRowAtIndexPath: 时调用它。从示例代码中不确定您在做什么。

您可以尝试将代码放入自定义单元格的drawRect: 以查看会发生什么。请注意,对于自定义单元格,这可能会棘手;您可能还需要考虑自定义 layoutSubviews

另外,对于它的价值,设置那些特定的 CALayer 属性可能会由于屏幕外渲染而产生减慢效果,但我认为这对你来说没什么大不了的,好像应该只发生在单元格创建时。

更新

我认为您需要将初始设置代码与在表格视图操作期间更新单元格内容的代码分开。在我看来,您在上面编写的初始设置代码应该只在创建单元格时运行一次。所以我收回我在上面第二段中写的内容;不要放在drawRect:

更多

查看 Apple 的文档 here。我不确定传递单元格样式的效果...如果在您覆盖 initWithStyle:reuseIdentifier: 时将样式传递给 super,那么是的,我认为 super 会使用它来设置单元格的内容视图。如果你然后用你自己的东西修改内容视图,那么 super 就是在做浪费的工作。至于您在“编辑:”下添加的其余代码,我认为它看起来不错。

不管怎样,只要我这样做,我都会使用 InterfaceBuilder。

【讨论】:

  • 这里看不懂,请将代码添加到您原来的问题中
  • 刚刚意识到您无法在回复中进行正确的格式化。将其添加到问题中。干杯。
  • 我最初的方法之一是将设置代码放在“initWithStyle”中,但我无法让它工作。理想情况下,这就是我想说的地方,因为它似乎最有意义。我一直在 Interface Builder 中布置单元格,但是为了更改细节,我必须更改代码,我希望它在单元格创建期间发生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
  • 2012-09-15
相关资源
最近更新 更多