UITableViewCell中的CALayer阴影绘制不正确

我使用CALayer将阴影应用于UITableViewCell。

这是我的代码:

- (void)addShadowToView:(UIView *)view { // shadow view.layer.shadowColor = [[UIColor colorWithWhite:0.0f alpha:0.1f] CGColor]; view.layer.shadowOpacity = 1.0f; view.layer.shadowOffset = CGSizeMake(0.0f, 3.0f); view.layer.shadowRadius = 6.0f; CGRect shadowFrame = view.layer.bounds; CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath; view.layer.shadowPath = shadowPath; } 

问题是,对于一些tableviewcells,阴影不会跨越单元格的整个宽度。 对于一些细胞来说,这是正确的,对于其他细胞来说是错误的。 我注意到设备的旋转也会影响它,重新加载tableview数据有时可以解决这个问题。

什么是最好的方法来缓解这个问题(并且我并不是说要重新加载整个tableview每轮等)?

正确应用阴影的单元格底部示例: 在这里输入图像说明

向下滚动之后,在同一个tableview中的单元格底部(阴影只应用于宽度的前75%): 在这里输入图像说明

编辑:我注意到这个问题是由这些代码行引起的:

 CGRect shadowFrame = view.layer.bounds; CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath; view.layer.shadowPath = shadowPath; 

如果我把它们排除在外,一切都很好。 但是我被告知使用这个有一定的性能好处。 不知何故阴影在旋转后不能正确应用于新的尺寸。

你可以为你的单元格框架覆盖setter,并调用addShadowToView: 您可以通过存储单元格的大小来进行优化,并且只在更改大小时更新阴影path,例如:

 @property (nonatomic, assign) CGSize size; 

 - (void) setFrame:(CGRect)frame { [super setFrame:frame]; // Need to check make sure this subview has been initialized if(self.subviewThatNeedsShadow != nil && !CGSizeEqualToSize(self.size,_frame.size) { [self addShadowToView: self.subviewThatNeedsShadow]; } } 

最简单的解决scheme是将阴影添加到UITableViewCell的contentView (与单元的后台视图的图层)。 由于单元格的边界在滚动上发生了变化,因此如果将阴影添加到根视图,则必须更新每个滚动事件上的阴影path,这将是昂贵而且不必要的。

你肯定是正确的:通过不明确地设置shadowPath,虽然性能命中。 如果在单元格中没有任何animation内容,我还build议将其栅格化以进一步提高性能。

编辑:你还必须确保当你设置的影子path的contentView的界限是在他们的“最后”的位置。 如果稍后修改了单元格的大小,则会导致contentView的边界更改,从而产生不正确的shadowPath。 解决方法是更新UITableViewCell的layoutSubviews方法中的path。