为什么 CAShapeLayer 颜色变化时会有一点延迟?

Why there is a little delay when CAShapeLayer color changes?

在我的应用程序中,我将自定义视图设置为 navigationBar.titleView 并将 tableView 添加到控制器。在自定义视图中有一个名为 GSSearchIcon 的 UIView 子类和一个 UILabel。

看起来像这样

我想做的是当tableView滚动时navigationBar.titleView的颜色(GSSearchIcon的颜色和UILabel的textColor的颜色)根据tableView.contentOffset

同时改变

但是,当tableView滚动时,UILabel的textColor立即改变,而GSSearchIcon的颜色改变有点延迟,可能有几百毫秒。

GSSearchIcon代码如下

#import "GSSearchIcon.h"

static const CGFloat kCircleRadius = 6.3;
static const CGFloat kIconWidth = 16;

@interface GSSearchIcon ()

@property (nonatomic, strong) CAShapeLayer *circleLayer;
@property (nonatomic, strong) CAShapeLayer *lineLayer;

@end

@implementation GSSearchIcon
- (instancetype)initIconWithFrame:(CGRect)frame {
    self = [super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, kIconWidth, kIconWidth)];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    self.backgroundColor = [UIColor clearColor];

    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(kCircleRadius, kCircleRadius) radius:kCircleRadius startAngle:0 endAngle:2 * M_PI clockwise:YES];
    _circleLayer = [[CAShapeLayer alloc] init];
    [_circleLayer setPath:circlePath.CGPath];
    [_circleLayer setStrokeColor:[UIColor gs_colorWithSameRGB:255 alpha:1].CGColor];
    [_circleLayer setFillColor:[UIColor clearColor].CGColor];
    [_circleLayer setLineWidth:1];
    [_circleLayer setStrokeStart:0];
    [_circleLayer setStrokeEnd:2 * M_PI];
    [self.layer addSublayer:_circleLayer];

    UIBezierPath *linePath = [UIBezierPath bezierPath];
    [linePath moveToPoint:CGPointMake(16 - (16 - 2 * kCircleRadius)* sqrt(2), 16 - (16 - 2 * kCircleRadius)* sqrt(2))];
    [linePath addLineToPoint:CGPointMake(16, 16)];
    _lineLayer = [[CAShapeLayer alloc] init];
    [_lineLayer setPath:linePath.CGPath];
    [_lineLayer setStrokeColor:[UIColor gs_colorWithSameRGB:255 alpha:1].CGColor];
    [_lineLayer setFillColor:[UIColor clearColor].CGColor];
    [_lineLayer setLineWidth:1];
    [self.layer addSublayer:_lineLayer];
}

- (void)setColor:(UIColor *)color {
    [self.circleLayer setStrokeColor:color.CGColor];
    [self.lineLayer setStrokeColor:color.CGColor];
}

@end

这是CAShapeLayer性能问题造成的吗?以及如何解决?提前致谢。

我不知道调用 setColor 方法的代码是什么样的,可能那里发生了什么。

但是,如果一切看起来都不错,而这实际上是一个性能问题,即改变颜色实际花费的时间,我可以建议一个更快的替代方案:

  1. 而不是你的GSSearchIcon,使用普通的UIImageView
  2. 您可以使用 PNG 文件作为图标,也可以使用已有的代码自行绘制。
  3. 使用 "Always Template" 渲染模式创建图像,以便您可以通过更改 tintColor 来更改图标颜色。

根据您的代码查看以下示例代码:

UIImageView 属性:

@property (nonatomic, strong) UIImageView *searchIconImageView;

绘制图标并创建 UIImageView:

UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(kCircleRadius, kCircleRadius) radius:kCircleRadius * 0.92 startAngle:0 endAngle:2 * M_PI clockwise:YES];
[circlePath stroke];

UIBezierPath *linePath = [UIBezierPath bezierPath];
[linePath moveToPoint:CGPointMake(16 - (16 - 2 * kCircleRadius)* sqrt(2), 16 - (16 - 2 * kCircleRadius)* sqrt(2))];
[linePath addLineToPoint:CGPointMake(16, 16)];
[linePath stroke];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

self.searchIconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kIconWidth, kIconWidth)];
self.searchIconImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.searchIconImageView.tintColor = [UIColor whiteColor];
[self.view addSubview:self.searchIconImageView];

要更改颜色:

self.searchIconImageView.tintColor = [UIColor redColor];

我很想知道这种方法是否解决了延迟问题..