在滚动后删除CALayer到UITableViewCell

我正在尝试将CALayer添加到我的UITableViewCell的底部以获得一些“影子”效果。 问题是当表格向上滚动并移出图层时,所以当你向下滚动时,它不可见。 如果从屏幕向下滚动单元格,然后备份,他们显得很好。

我有一个GIF在这里显示发生了什么事情。

这是我如何做到这一点:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"CellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } cell.textLabel.text = [NSString stringWithFormat:@"Row %d", (int)indexPath.row]; CALayer *bottomBorder = [CALayer layer]; bottomBorder.frame = CGRectMake(0.0f, cell.frame.size.height, cell.frame.size.width, 1.0f); bottomBorder.backgroundColor = [UIColor colorWithWhite:0.9f alpha:1.0f].CGColor; [cell.layer addSublayer:bottomBorder]; cell.clipsToBounds = NO; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } 

我也尝试过为每个单元格使用唯一的cellIdentifier,希望它们不会被重用,因此层不会像这样被删除:

  //Same code as before just this changed UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%ld_%ld", (long)indexPath.row, (long)indexPath.section]]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:@"%ld_%ld", (long)indexPath.row, (long)indexPath.section]]; } //Same code continued... 

所以我的问题是,当一个单元格被重用,CALayer添加到它被删除。 当单元格从屏幕上滚动并重新开始时,我需要做些什么才能保留该图层。

编辑:

我也试过这不起作用:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"CellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; CALayer *bottomBorder = [CALayer layer]; bottomBorder.frame = CGRectMake(0.0f, cell.frame.size.height, cell.frame.size.width, 1.0f); bottomBorder.backgroundColor = [UIColor colorWithWhite:0.9f alpha:1.0f].CGColor; [cell.layer addSublayer:bottomBorder]; cell.clipsToBounds = NO; cell.selectionStyle = UITableViewCellSelectionStyleNone; } cell.textLabel.text = [NSString stringWithFormat:@"Row %d", (int)indexPath.row]; return cell; } 

GACK! 不要为每个单元格使用不同的单元格标识符。 这完全击败了细胞再利用机制,并将给你不断增加的内存使用,并迫使你总是为每个索引创build一个新的细胞 – 一个可能的最坏的结果。

每当一个单元格在屏幕外滚动,就会进入重用队列。 然后,当一个新的索引path滚动到视图中时,系统会将之前使用的单元格从回收站中取出并交给您。 你应该假设它的结构是完全形成的(你添加的任何自定义字段将在那里),但是内容都是错误的,并且需要完全设置。 所以如果你有一个带有3个标签的单元格,并且你的模型中的一些对象将文本填充到1个标签中,一些标签分为2个标签,而另外一些标签分成3个标签,那么即使它们是空的,也应该为所有3个标签设置一个值串。 这样可以防止上次使用单元时留下的值继续存在。

这有点像医生的办公室,有病人填写表格。 你填写一张表格交给店员。 店员把信息input电脑,然后把表格放回空白的表格上。 下一个病人必须从表格中删除一切,包括如果没有任何孩子,配偶,他们没有的预先存在的条件等的孩子的名字等。否则,来自最后一个人使用的信息表格将仍然在你的表格上。

至于你的阴影层,当你使用dequeueReusableCellWithIdentifier获取一个单元格时,如果你必须创build一个新的单元格,你应该只添加你的图层。 如果您找回重复使用的单元格,图层将已经存在,但是如果它们在单元格之间切换,则可能需要设置它的内容。

原来,它被删除的原因是因为CALayer被添加到单元格而不是UITableViewCell contentView 。 所以正确的实施如下:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"CellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; CALayer *bottomBorder = [CALayer layer]; bottomBorder.frame = CGRectMake(0.0f, (CGRectGetHeight(cell.contentView.bounds) - 1), CGRectGetWidth(cell.contentView.bounds), 1.0f); bottomBorder.backgroundColor = [UIColor colorWithWhite:0.9f alpha:1.0f].CGColor; [cell.contentView.layer addSublayer:bottomBorder]; } cell.textLabel.text = [NSString stringWithFormat:@"Row %d", (int)indexPath.row]; return cell; }