ios - 如何在单个表中使用两个不同的自定义 UITableViewCell 子类?

标签 ios cocoa-touch uitableview

如何正确显示到同一 UITableView 中的不同 UITableViewCell 子类?

我正在使用 Storyboard来回答这个问题。我正在尝试在单个表中使用 UITableView 单元格的两个不同子类。 TTTextFieldCell 的想法知道如何显示文本框和 TTPickerCell s 知道如何向用户呈现 UIPicker。那里有协议(protocol)TTTableViewCell指定单个选择器:[setCellDetails (NSDictionary*) cellDetails]每个UITableViewCell子类知道如何使用 cellDetails Dictionary 来设置单元格。

-(NSArray *)tableData {
     if (!_tableData) {
          _tableData =
          @[ // Sections
             @{ // Section Details
                  kSectionName:@"Scout Information"
                  ,kRows:@[ // Rows
                             @{// Cell Details
                                  kBoundProperty:self.scoutName
                                  ,kReuseIdentifier:kTextFieldCell
                                  ,kLabel:@"Name"
                                  ,kPlaceholderValue:@"Scout's Name"
                                  }
                             ,@{
                                  kReuseIdentifier:@"TTPickerCell"
                                  ,kLabel:@"Type"
                                  ,kPlaceholderValue:@"Cadet, Junior, etc..."
                                  }
                             ,@{
                                  kBoundProperty:self.yearsScouting
                                  ,kReuseIdentifier:kTextFieldCell
                                  ,kLabel:@"Years"
                                  ,kPlaceholderValue:@"Years of Experience"
                                  ,kKeyboardStyle:@(UIKeyboardTypeNumberPad)
                                  }
                             ]
                  }
             ,@{ // Section Details
                  kSectionName:@"Parent Information"
                  ,kRows:@[
                             @{
                                  kBoundProperty:self.parentName
                                  ,kReuseIdentifier:kTextFieldCell
                                  ,kLabel:@"Name"
                                  ,kPlaceholderValue:@"Parents's Name"
                                  }
                             ]
                  }
             ];
     }
     return _tableData;
}


- (void)viewDidLoad
{
     [super viewDidLoad];
    // Do any additional setup after loading the view.
    // Line A
     [self.tableView registerClass:[TTTextFieldCell class] forCellReuseIdentifier:@"TTTextFieldCell"];
    // Line B
     [self.tableView registerClass:[TTPickerCell class] forCellReuseIdentifier:@"TTPickerCell"];
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     NSDictionary* cellDetails = self.tableData[indexPath.section][kRows][indexPath.row];

     NSString* reuseIdentifier = cellDetails[kReuseIdentifier];

     // Line C
     UITableViewCell<TTTableViewCell> *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

     [cell setCellDetails:cellDetails];
     return cell;
}

现在,问题来了。如果我注释掉 A 和 B 行,那么 TTTextFieldCells 会正确显示。但是 C 行会失败,因为它试图用 TTPickerCell 对象调用 TTTextFieldCell init,并且因为 TTPickerCell 对象没有相同的属性而失败。如果我取消注释 A 和 B 行,则单元格样式默认为 UITableViewCellStyleDefault他们不显示自定义控件。奇怪的是,如果我注释掉 A 行,取消注释 B 行,那么 TTTextFieldCells看起来不错,但是 TTPickerCells默认为 UITableViewCellStyleDefault .

似乎如果我不注册一个类,出队将返回第一个原型(prototype)单元类的实例。如果我注册类(class),则单元格默认为 UITableViewCellStyleDefault .

另外值得注意的是,initWithStyle:reuseIdentifier: 选择器只有在类被注册时才会被调用。

那么,如何在同一个 UITableView 中正确显示到不同的 UITableViewCell 子类?我必须放弃使用 Storyboard 来设计单元吗?

先感谢您。

最佳答案

你不想调用 tableView registerClass:... cellForRowAtIndexPath 内部.相反,您应该一次注册您的类(class)/ Nib 。这通常在 Controller 的 viewDidLoad 中完成。方法。您的 cellForRowAtIndexPath然后实现看起来像这样:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary* cellDetails = self.tableData[indexPath.section][kRows][indexPath.row];

    NSString *reuseIdentifier = (/*some condition*/ ? @"TTTextFieldCell" : @"TTPickerCell");
    UITableViewCell<TTTableViewCell> *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    [cell setCellDetails:cellDetails];
    return cell;
}

编辑:我应该提到 dequeueReusableCellWithIdentifier从 iOS 6 开始总是返回一个单元格。如果您的目标是早期版本的 iOS,即使此方法返回 nil,您也需要考虑创建单元格。

关于ios - 如何在单个表中使用两个不同的自定义 UITableViewCell 子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20690037/

相关文章:

ios voip应用程序可以在后台运行吗?

objective-c - UIButton 不可点击

ios - 在后台获取定期位置更新

iphone - uitableviewcell 的自定义选择样式颜色

ios - 通用链接(深度链接)不适用于 iPhone 但适用于 iPad

ios - 使用 6 次重复测试 TapGesture(iOS 和 Swift)

ios - 如何使用 UILongPressGestureRecognizer 计算长按按钮的时间

objective-c - 使用 CGImageMaskCreate 创建蒙版是全黑的(iphone)

ios - UiView 固定在 UiTableViewController 之上

ios - iOS 7上UITableView行删除动画闪烁