【问题标题】:Two types of cells in tableView - elegancytableView 中的两种类型的单元格 - 优雅
【发布时间】:2013-09-11 08:51:52
【问题描述】:

您将如何优雅地在同一个 tableView 中编写两种类型的单元格?

显然我可以这样做:

NSDictionary *cellInfo = [_userInformation objectAtIndex:indexPath.row];
NSString *cellType = [cellInfo objectForKey:@"type"];
if ([cellType isEqualToString:kProfileImage]) {
    ProfileImageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"profileImageCell"];
    cell.descriptionLabel.text = [cellInfo objectForKey:@"cellLabelText"];
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    return cell;
}
else {
    AccountCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AccountCell"];
    cell.descriptionLabel.text = [cellInfo objectForKey:@"cellLabelText"];
    cell.textField.placeholder = [cellInfo objectForKey:@"textFieldPlaceholder"];
    cell.textField.delegate = self;
    cell.textField.clearButtonMode = UITextFieldViewModeWhileEditing;
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    return cell;
}
return nil;

但是我的老师总是告诉我不要写两次,如果它在两种情况下都发生,并且如你所见,两种情况下有 3 行是相同的。我想将它们移到 if 之外,并且只在 if 正文中保留针对每种情况的特定行。

【问题讨论】:

  • 下面的答案很好,但在我看来,虽然你不应该“写两次”你这样做的方式完全没问题。

标签: ios objective-c uitableview coding-style


【解决方案1】:

您可以通过根据类型实例化单元格来做得更好,但将单元格定义为 UITableViewCell 并在方法结束时返回实例。这也将允许您为这些单元可能共享的每个公共属性只写一行。比如:

UICustomTableViewCell *cell = nil; //This cell type is a common super class of both cell classes
NSDictionary *cellInfo = [_userInformation objectAtIndex:indexPath.row];
NSString *cellType = [cellInfo objectForKey:@"type"];
if ([cellType isEqualToString:kProfileImage]) {
    cell = [tableView dequeueReusableCellWithIdentifier:@"profileImageCell"];
}
else 
{
    cell = [tableView dequeueReusableCellWithIdentifier:@"AccountCell"];
    ((AccountCell*) cell).textField.placeholder = [cellInfo objectForKey:@"textFieldPlaceholder"];
    ((AccountCell*) cell).textField.delegate = self;
    ((AccountCell*) cell).textField.clearButtonMode = UITextFieldViewModeWhileEditing;
}
cell.delegate = self;
cell.descriptionLabel.text = [cellInfo objectForKey:@"cellLabelText"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//Any other common properties can by assigned here

return cell;

在本例中,两种单元格类型都有一个共同的“委托”属性。

【讨论】:

  • 但如果我这样做,我将无法访问 descriptionLabel / textField,对吗?
  • 正确,这就是为什么两者都应该从同一个自定义超类继承。更新答案
  • 哦,所以对于这种情况,我需要创建 3 个单元类。 (一个超类,继承 UITableViewCell 并具有共享属性,以及两个继承超类的子类,具有自定义属性)。是的,你刚刚帮我理解了继承。
  • 另外,我应该在第二种情况下应用强制转换,以便单元格访问属性:((AccountCell*) cell)。
  • 也是如此。很高兴能帮到你。
【解决方案2】:

您可以在开头将单元格声明为“id”或 UITableViewCell。

NSDictionary *cellInfo = [_userInformation objectAtIndex:indexPath.row];
NSString *cellType = [cellInfo objectForKey:@"type"];
UITableViewCell* cell = nil;
if ([cellType isEqualToString:kProfileImage]) {
    cell = [tableView dequeueReusableCellWithIdentifier:@"profileImageCell"];
}
else {
    cell = [tableView dequeueReusableCellWithIdentifier:@"AccountCell"];
    cell.textField.placeholder = [cellInfo objectForKey:@"textFieldPlaceholder"];
        cell.textField.delegate = self;
    cell.textField.clearButtonMode = UITextFieldViewModeWhileEditing;
}

cell.descriptionLabel.text = [cellInfo objectForKey:@"cellLabelText"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

return cell;

但是,如果您想调用这些自定义类的方法或属性,您可能需要进行一些类型转换。

((AccountCell*) cell).accountCellProperty = @"smth";

【讨论】:

  • 啊,是的,我错过了选角。至少我学到了更多的东西;)。但在那种情况下,我仍然做不到,因为在 if 之后,我不知道需要将其转换为哪种类型(例如:AccountCell / ProfileImageCell),尽管它们共享属性。
  • 强制转换只能在“if else”部分进行。如果您在这些类之间有一些共享属性,我建议让基类 MyTableViewCell 扩展 UITableViewCell - 并在此处添加共享属性 - 并使用它而不是 UITableViewCell。并且您的类 AccountCell 应该扩展 MyTableViewCell。
【解决方案3】:

重构上述代码的最佳方法是:

NSDictionary *cellInfo = [_userInformation objectAtIndex:indexPath.row];
NSString *cellType = [cellInfo objectForKey:@"type"];
UITableViewCell *aCell = nil;

if ([cellType isEqualToString:kProfileImage]) {
    aCell = [tableView dequeueReusableCellWithIdentifier:@"profileImageCell"];
} else {
    aCell = [tableView dequeueReusableCellWithIdentifier:@"AccountCell"];
    ((ProfileImageCell *)aCell).descriptionLabel.text = [cellInfo objectForKey:@"cellLabelText"];
    ((ProfileImageCell *)cell).textField.clearButtonMode = UITextFieldViewModeWhileEditing;


}

aCell.textField.delegate = self;
aCell.descriptionLabel.text = [cellInfo objectForKey:@"cellLabelText"];
[aCell setSelectionStyle:UITableViewCellSelectionStyleNone];
return aCell;

注意: *1。您不应该在一个方法中使用 return 多个语句。 2. ((ProfileImageCell )aCell):这是一种将“aCell”对象类型转换为“ProfileImageCell”类型的简单方法,因为“textField”不是 UITableViewCell 的属性。

【讨论】:

  • 是的,但我仍然无法在 if 语句之后访问 aCell.textField,因为我不知道是否应该将其转换为 ProfileImageCell 或 AccountCell,尽管它们具有相同的属性。跨度>
  • @LordZsolt :我认为您在谈论.. aCell.textLabel 因为 UITableViewCell 没有 textField 属性。
  • 使用“aCell.textField”您无法访问“textField”属性,因为对于编译器,aCell 是 UITableViewCell 类型,而在这种情况下“textField”是您的自定义类的属性。因此,每次您必须访问自定义类方法/属性时,您都需要进行类型转换 ((CustomClass *)aCell).property,其中 aCell 是 CustomClass 的 SuperClass 类型的对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多