为什么 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
方法的代码是什么样的,可能那里发生了什么。
但是,如果一切看起来都不错,而这实际上是一个性能问题,即改变颜色实际花费的时间,我可以建议一个更快的替代方案:
- 而不是你的
GSSearchIcon
,使用普通的UIImageView
。
- 您可以使用 PNG 文件作为图标,也可以使用已有的代码自行绘制。
- 使用 "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];
我很想知道这种方法是否解决了延迟问题..
在我的应用程序中,我将自定义视图设置为 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
方法的代码是什么样的,可能那里发生了什么。
但是,如果一切看起来都不错,而这实际上是一个性能问题,即改变颜色实际花费的时间,我可以建议一个更快的替代方案:
- 而不是你的
GSSearchIcon
,使用普通的UIImageView
。 - 您可以使用 PNG 文件作为图标,也可以使用已有的代码自行绘制。
- 使用 "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];
我很想知道这种方法是否解决了延迟问题..