方法有问题:prepareForReuse
Having problems with the method: prepareForReuse
我有一个自定义 UITableViewCell
,当它被 selected 时,它会扩展并向 selected 单元格 UIView
添加一个 UILabel
我在故事板中添加了。
当我 运行 应用程序和 select 单元格时,标签会按预期添加到 myView
。问题是,当我向下滚动时,标签也显示在另一个单元格中。
显然,它之所以如此,是因为我正在重复使用电池,但我没有像 Emilie 所说的那样清洁它们。我正在尝试调用 prepareForReuse
和 'cleaning' 单元格的方法,但我无法做到这一点。这是我的代码:
- (void)prepareForReuse {
NSArray *viewsToRemove = [self.view subviews];
for (UILablel *v in viewsToRemove) {
[v removeFromSuperview];
}
这样做,甚至可以清除 selected 单元格标签。
- (void)viewDidLoad {
self.sortedDictionary = [[NSArray alloc] initWithObjects:@"Californa", @"Alabama", @"Chicago", @"Texas", @"Colorado", @"New York", @"Philly", @"Utah", @"Nevadah", @"Oregon", @"Pensilvainia", @"South Dekoda", @"North Dekoda", @"Iowa", @"Misouri", @"New Mexico", @"Arizona", @"etc", nil];
self.rowSelection = -1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
return customCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
CategorieCell *customCell = (CategorieCell *)[tableView cellForRowAtIndexPath:indexPath];
if (self.info) {
[self.info removeFromSuperview];
}
self.info = [[UILabel alloc] init];
[self.info setText:@"Hello"];
[self.info setBackgroundColor:[UIColor brownColor]];
CGRect labelFrame = CGRectMake(0, 0, 50, 100);
[self.info setFrame:labelFrame];
[customCell.infoView addSubview:self.info];
NSLog(@"%ld", (long)indexPath.row);
self.rowSelection = [indexPath row];
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath row] == self.rowSelection) {
return 159;
}
return 59;
}
答案很简单:你像你应该的那样重复使用你的细胞,但从不清洗它们
重用您的 UITableViewCell
意味着您之前单击的单元格在屏幕外时将被重用。
点击后,您会在 UITableViewCell
中添加一个视图。重用时,视图仍然存在,因为您永远不会删除它。
您有两个选择:一,您可以设置 self.info 视图的标签(或检查您保存在内存中的索引路径),然后检查您何时将单元格出列,如果信息视图在那里,然后将其删除。更简洁的解决方案是通过覆盖自定义 UITableViewCell
的 prepareForReuse
方法来实现视图删除
精度
您需要做的第一件事是在初始化后为您的 self.info 视图设置一个标签:
[self.info setTag:2222];
如果您想使其尽可能简单,您可以直接在 cellForRowAtIndexPath
方法中检查并删除 self.info 视图:
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
if [customCell.infoView viewWithTag: 2222] != nil {
[self.info removeFromSuperview]
}
return customCell;
我不确定这段代码能否编译,我现在无法在我这边进行测试。希望有用!
我有一个自定义 UITableViewCell
,当它被 selected 时,它会扩展并向 selected 单元格 UIView
添加一个 UILabel
我在故事板中添加了。
当我 运行 应用程序和 select 单元格时,标签会按预期添加到 myView
。问题是,当我向下滚动时,标签也显示在另一个单元格中。
显然,它之所以如此,是因为我正在重复使用电池,但我没有像 Emilie 所说的那样清洁它们。我正在尝试调用 prepareForReuse
和 'cleaning' 单元格的方法,但我无法做到这一点。这是我的代码:
- (void)prepareForReuse {
NSArray *viewsToRemove = [self.view subviews];
for (UILablel *v in viewsToRemove) {
[v removeFromSuperview];
}
这样做,甚至可以清除 selected 单元格标签。
- (void)viewDidLoad {
self.sortedDictionary = [[NSArray alloc] initWithObjects:@"Californa", @"Alabama", @"Chicago", @"Texas", @"Colorado", @"New York", @"Philly", @"Utah", @"Nevadah", @"Oregon", @"Pensilvainia", @"South Dekoda", @"North Dekoda", @"Iowa", @"Misouri", @"New Mexico", @"Arizona", @"etc", nil];
self.rowSelection = -1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
return customCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
CategorieCell *customCell = (CategorieCell *)[tableView cellForRowAtIndexPath:indexPath];
if (self.info) {
[self.info removeFromSuperview];
}
self.info = [[UILabel alloc] init];
[self.info setText:@"Hello"];
[self.info setBackgroundColor:[UIColor brownColor]];
CGRect labelFrame = CGRectMake(0, 0, 50, 100);
[self.info setFrame:labelFrame];
[customCell.infoView addSubview:self.info];
NSLog(@"%ld", (long)indexPath.row);
self.rowSelection = [indexPath row];
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath row] == self.rowSelection) {
return 159;
}
return 59;
}
答案很简单:你像你应该的那样重复使用你的细胞,但从不清洗它们
重用您的 UITableViewCell
意味着您之前单击的单元格在屏幕外时将被重用。
点击后,您会在 UITableViewCell
中添加一个视图。重用时,视图仍然存在,因为您永远不会删除它。
您有两个选择:一,您可以设置 self.info 视图的标签(或检查您保存在内存中的索引路径),然后检查您何时将单元格出列,如果信息视图在那里,然后将其删除。更简洁的解决方案是通过覆盖自定义 UITableViewCell
prepareForReuse
方法来实现视图删除
精度
您需要做的第一件事是在初始化后为您的 self.info 视图设置一个标签:
[self.info setTag:2222];
如果您想使其尽可能简单,您可以直接在 cellForRowAtIndexPath
方法中检查并删除 self.info 视图:
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
if [customCell.infoView viewWithTag: 2222] != nil {
[self.info removeFromSuperview]
}
return customCell;
我不确定这段代码能否编译,我现在无法在我这边进行测试。希望有用!