如何正确显示到同一 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/