
[英]Using dequeueReusableCellWithIdentifier for custom cells
[英]dequeueReusableCellWithIdentifier and custom cells
好的,我有一张包含3个不同原型单元格的表格(cellVaccination,cellAdmin,cellExpire)。 在我的cellForRowAtIndexPath方法中,我将Core Data对象划分为这3个单独的单元格,因此该表在结构上将如下所示:
- Drug 1
- Drug 1 Admin
- Drug 1 Expire
- Drug 2
- Drug 2 Admin
- Drug 2 Expire
- Drug 3
- Drug 3 Admin
- Drug 3 Expire
此外,我已通过编程方式将UISwitch添加到“顶层”单元格(即Drug 1)中,以便该开关可以控制辅助单元格的功能(即颜色,文本等)。 这是我当前的cellForRowAtIndexPath的样子:
- (VaccineTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// we need to adjust the indexPath because we split a single core data object into 3 different rows
NSIndexPath *adjustedIndexPath = [NSIndexPath indexPathForRow:indexPath.row / 3 inSection:indexPath.section];
Vaccine *vaccine = [self.fetchedResultsController objectAtIndexPath:adjustedIndexPath];
// define the switch that will get added to the primary table rows
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
if (indexPath.row % 3 == 0) {
static NSString *cellIdentifier = @"cellVaccination";
VaccineTableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
cell.vaccineName.text = vaccine.vaccineName;
// add a switch into that table row
cell.accessoryView = switchview;
[switchview addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
switchview.tag = indexPath.row;
switchview.on = [vaccine.vaccineEnabled boolValue];
// PROBLEM AREA BELOW
if (switchview.on) {
VaccineTableViewCell *cell1 = [myTableView dequeueReusableCellWithIdentifier:@"cellAdmin" forIndexPath:[NSIndexPath indexPathForItem:indexPath.row + 1 inSection:0]];
cell1.vaccineAdmin.textColor = [UIColor redColor];
cell1.vaccineAdminDate.textColor = [UIColor redColor];
NSLog(@"Row %d is %@", indexPath.row, switchview.on ? @"ON" : @"OFF");
} else {
VaccineTableViewCell *cell1 = [myTableView dequeueReusableCellWithIdentifier:@"cellAdmin" forIndexPath:[NSIndexPath indexPathForItem:indexPath.row + 1 inSection:0]];
cell1.vaccineAdmin.textColor = [UIColor lightGrayColor];
cell1.vaccineAdminDate.textColor = [UIColor lightGrayColor];
NSLog(@"Row %d is %@", indexPath.row, switchview.on ? @"ON" : @"OFF");
}
//
return cell;
}
else if (indexPath.row % 3 == 1) {
VaccineTableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:@"cellAdmin" forIndexPath:indexPath];
cell.vaccineAdminDate.text = vaccine.vaccineAdmin;
return cell;
}
else if (indexPath.row % 3 == 2) {
VaccineTableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:@"cellExpire" forIndexPath:indexPath];
cell.vaccineExpireDate.text = vaccine.vaccineExpire;
return cell;
}
else {
// do nothing at the moment
}
}
我遇到的问题似乎出在“问题下方区域”元素内指定的区域附近,更具体地说,我猜的是dequeueReusableCellWithIdentifier。 从理论上讲,应该发生的情况是,当第一次通过Core Data对象填充单元格时,我想测试开关是“打开”还是“关闭”,并适当调整参数(例如颜色),以便这意味着,在没有任何其他交互的情况下,相应的行将进行适当的着色。
这是怎么回事-假设我在iPhone 4S上进行模拟,并且屏幕显示的是4行集,或总共显示12行(4行包含3个不同的原型)。 而且我们还假设前两个已打开,第二个已关闭,再次直接从Core Data驱动。 最初,屏幕将看起来正确,前两个项目被染成红色,而后两个项目被染成灰色。 但是,当我开始向上滚动表格时,下两个(不在屏幕上)显示为红色,因此模式继续。 奇怪的是,当NSLog返回行标识符(在“问题区域”部分中看到)时,所有内容似乎都在标识正确的行,但显然不是,例如:
vaccinations[10952:1486529] Row 0 is ON
vaccinations[10952:1486529] Row 3 is ON
vaccinations[10952:1486529] Row 6 is OFF
vaccinations[10952:1486529] Row 9 is OFF
vaccinations[10952:1486529] Row 12 is OFF
vaccinations[10952:1486529] Row 15 is OFF
我相信这与dequeueReusableCellWithIdentifier方法有关,但是,为什么NSLog会正确识别行,但是颜色的变化却没有击中正确的行?
您具有对cell1
引用,在其中要为另一个NSIndexPath
出队一个单元,配置该单元的颜色,然后丢弃该单元。 我猜您正在尝试调整其他单元格(下一个单元格)的视觉外观。
那是不对的。 cellForRowAtIndexPath
应该仅调整当前单元格的状态。 如果要调整cellAdmin
单元格的外观, cellAdmin
在if (indexPath.row % 3 == 1) ...
块内执行此操作。
因此,将在模型中查找if (indexPath.row % 3 == 0)
块,以确定开关是打开还是关闭。 if (indexPath.row % 3 == 1)
块将在模型中查找以确定文本应为哪种颜色。
但是cellForRowAtIndexPath
不应尝试调整另一个单元格的外观。 您无法保证这些实例化的顺序(它可能会根据您是否滚动,从哪个方向等而变化)。
如果确实要更新另一个可见的单元格,则无论如何dequeueReusableCellWithIdentifier
都不是正确的方法。 相反,可以使用[tableView cellForRowAtIndexPath:]
来为当前可见的单元格检索单元格(并且一定不要与类似名称的UITableViewDataSource
方法混淆)。 但是您永远不会在这种情况下这样做,因为您不知道其他单元是否已加载。 (实际上,我认为在任何情况下都更新另一个单元格是一种坏习惯,这违反了职责分离。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.