重用的 tableView 单元格不调用 layoutSubviews 方法
Posted
技术标签:
【中文标题】重用的 tableView 单元格不调用 layoutSubviews 方法【英文标题】:Reused tableView cells not calling layoutSubviews method 【发布时间】:2014-08-02 01:54:44 【问题描述】:我有一个自定义 tableViewCell
类,在我的 tableView 单元格中我有一个自定义 UIView
。每个 tableView 单元格都与一个唯一的UIBezierPath
相关联,该UIBezierPath
设置为等于视图path
属性。为了呈现路径,必须调用layoutSubviews
。我注意到我的前 5 个单元格调用了 layoutSubviews
,但接下来的 5 个单元格没有调用 layoutSubviews
,因此它们的路径最终不会被渲染,它们最终只是重用了前 5 个单元格的路径。由于后 5 个单元格只是重复使用前 5 个单元格,我如何为每个单元格调用 layOutSubviews
?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString* identifier = @"audioTableCell";
OSAudioTableCell *cell = [self.audioTable dequeueReusableCellWithIdentifier:identifier];
if(cell == nil)
cell = [[OSAudioTableCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: identifier];
Recording * recording = [self.managedDocument.frc objectAtIndexPath:indexPath];
cell.waveView.path = nil;
cell.waveView.minAmpl = [recording.minAmpl floatValue];
NSData * pathData = recording.waveData;
//Setting the path
cell.waveView.path = [NSKeyedUnarchiver unarchiveObjectWithData:pathData];
[cell setImageSize:cell.waveView.bounds.size];
//这是我的自定义 UIView 类 waveView 中第一个被调用的方法
-(void) layoutSubviews
if (!self.blueWave)
self.blueWave = [self createShapeLayer];
self.blueWave.strokeColor = [UIColor colorWithRed:107/255.0f green:212/255.0f blue:231/255.0f alpha:1.0f].CGColor;
self.redWave = [self createShapeLayer];
self.redWave.strokeColor = [UIColor redColor].CGColor;
self.redWave.strokeEnd = self.progress;
[self.layer addSublayer:self.blueWave];
[self.layer insertSublayer:self.redWave above:self.blueWave];
[self render];
【问题讨论】:
打电话给[super layoutSubviews]
很重要
我会在哪里称呼它?
作为 layoutSubviews 的第一行。
@rmaddy 实现了它,但没有任何区别。如果我调用 [self.waveView layoutSubviews];在cellForRowAtIndexPath
中,它将调用每个单元格的方法,这很好。但是,第二组 5 个单元格将分别呈现正确的路径以及它们正在重用的单元格的路径。
永远不要直接调用 layoutSubviews。
【参考方案1】:
因此,无论我尝试什么,layOutSubviews
都不会被我重复使用的单元格调用。我试图将 UIView
路径设置为 nil 然后调用 setNeedsLayout
但这没有任何作用。我尝试清除prepareForReuse
中的路径,但仍然没有运气。我必须做的是在重复使用单元格时手动删除CAShapeLayers
。成功了。
if(cell == nil)
cell = [[OSAudioTableCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: identifier];
else
[cell.waveView.blueWave removeFromSuperlayer];
[cell.waveView.redWave removeFromSuperlayer];
cell.waveView.blueWave = nil;
cell.waveView.redWave = nil;
cell.waveView.path = nil;
cell.trackLabel.text = nil;
【讨论】:
【参考方案2】:对于现在偶然发现此答案并遇到相同问题的任何人:
我通过将计算层的新路径的函数放在 UICollectionViewCell 类中的 override layoutSubviews() 函数中的单独 DispatchQueue 块中来修复它。
override func layoutSubviews()
super.layoutSubviews()
DispatchQueue.main.async
self.shapeLayer.path = UIBezierPath(roundedRect: viewBubbleBase.bounds, cornerRadius: bubbleCornerRadius).cgPath
【讨论】:
以上是关于重用的 tableView 单元格不调用 layoutSubviews 方法的主要内容,如果未能解决你的问题,请参考以下文章