不要在 cellForRowAtIndexPath 中添加现有项目
Do not add an existing item in the cellForRowAtIndexPath
在我的 TableViewController 中,我使用自定义单元格,这个单元格有一个滚动视图。我的 cellForRowAtIndexPath 方法如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
// iOS 7 separator
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
cell.separatorInset = UIEdgeInsetsZero;
}
}
UIView *subview = [cell viewWithTag:indexPath.row + 1];
if (!subview) {
//... Set up the new cell
[self addScrollViewForCell:cell andCellIndx:indexPath.row];
}
else {
// ... Reuse the cell
}
return cell;
}
如果视图已经存在 - 我尝试不添加滚动视图。如果没有- 添加。
addScrollViewForCell:方法:
- (void)addScrollViewForCell: (CustomCell *)tCell andCellIndx:(NSInteger)cIndx {
UIScrollView * myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(5, 62, 350, 61)];
myScrollView.accessibilityActivationPoint = CGPointMake(100, 100);
//Some settings
// ...
UILabel *lblH = [[UILabel alloc] init];
lblH.textAlignment = NSTextAlignmentCenter;
lblH.text = strWeekIdntfr;
lblH.textColor = [UIColor blueColor];
lblH.frame = CGRectMake(offsetScores, 0, cCurrWeekBallsWidth, 15);
[myScrollView addSubview:lblH];
myScrollView.tag = cIndx + 1;
[tCell addSubview:myScrollView];
}
问题是 - 当我将 table 滚动到底部或向上时,开始添加 scrollView。通过标签检查视图我尝试区分可重复使用的和新的单元格,但这没有用。我该如何解决?
原因是因为 UITableViewCell
的实例在您滚动时被重复使用。
每次重复使用时,此行 UIView *subview = [cell viewWithTag:indexPath.row + 1];
将查询具有不同 tag
的视图。比如说,您在此 UITableView
中有 100 个单元格,可能会要求一个单元格提供标签 1、6、11、16、21 ... 96,显然它没有。所以它很可能在每次被重用时创建一个新的视图。将它与池中的每个单元格相乘,你会得到大量添加到它们的新滚动视图。
要解决此问题:只需使用修复 tag
号码。
所以行。
UIView *subview = [cell viewWithTag:indexPath.row + 1];
成为:
UIView *subview = [cell viewWithTag:1];
并且:
myScrollView.tag = cIndx + 1;
成为:
myScrollView.tag = 1;
正如@AdamPro13 指出的那样,更好、更优雅的方法是将滚动视图创建为自定义单元格的一部分。只需将它放在 UITableViewCell
子类的 initWithFrame:style:
中即可。
我发现最好的方法就是清除 scrollView 中的所有子视图。例如像这样:
[myCell.scrollView.subviewsmakeObjectsPerformSelector:@selector(removeFromSuperview)];
在我的 TableViewController 中,我使用自定义单元格,这个单元格有一个滚动视图。我的 cellForRowAtIndexPath 方法如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
// iOS 7 separator
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
cell.separatorInset = UIEdgeInsetsZero;
}
}
UIView *subview = [cell viewWithTag:indexPath.row + 1];
if (!subview) {
//... Set up the new cell
[self addScrollViewForCell:cell andCellIndx:indexPath.row];
}
else {
// ... Reuse the cell
}
return cell;
}
如果视图已经存在 - 我尝试不添加滚动视图。如果没有- 添加。 addScrollViewForCell:方法:
- (void)addScrollViewForCell: (CustomCell *)tCell andCellIndx:(NSInteger)cIndx {
UIScrollView * myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(5, 62, 350, 61)];
myScrollView.accessibilityActivationPoint = CGPointMake(100, 100);
//Some settings
// ...
UILabel *lblH = [[UILabel alloc] init];
lblH.textAlignment = NSTextAlignmentCenter;
lblH.text = strWeekIdntfr;
lblH.textColor = [UIColor blueColor];
lblH.frame = CGRectMake(offsetScores, 0, cCurrWeekBallsWidth, 15);
[myScrollView addSubview:lblH];
myScrollView.tag = cIndx + 1;
[tCell addSubview:myScrollView];
}
问题是 - 当我将 table 滚动到底部或向上时,开始添加 scrollView。通过标签检查视图我尝试区分可重复使用的和新的单元格,但这没有用。我该如何解决?
原因是因为 UITableViewCell
的实例在您滚动时被重复使用。
每次重复使用时,此行 UIView *subview = [cell viewWithTag:indexPath.row + 1];
将查询具有不同 tag
的视图。比如说,您在此 UITableView
中有 100 个单元格,可能会要求一个单元格提供标签 1、6、11、16、21 ... 96,显然它没有。所以它很可能在每次被重用时创建一个新的视图。将它与池中的每个单元格相乘,你会得到大量添加到它们的新滚动视图。
要解决此问题:只需使用修复 tag
号码。
所以行。
UIView *subview = [cell viewWithTag:indexPath.row + 1];
成为:
UIView *subview = [cell viewWithTag:1];
并且:
myScrollView.tag = cIndx + 1;
成为:
myScrollView.tag = 1;
正如@AdamPro13 指出的那样,更好、更优雅的方法是将滚动视图创建为自定义单元格的一部分。只需将它放在 UITableViewCell
子类的 initWithFrame:style:
中即可。
我发现最好的方法就是清除 scrollView 中的所有子视图。例如像这样:
[myCell.scrollView.subviewsmakeObjectsPerformSelector:@selector(removeFromSuperview)];