首页  >  问答  >  正文

iOS CGContext 画图在 UIView和CALayer用相同代码画出来之后线有差异?

这是图,上面的是用UIView,下面的使用CALayer。明显Layer上面有锯齿。这种个情况如何解决呢?

代码如下

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 10);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);

CGContextBeginPath(ctx);

NSArray *xs = @[@(10),@(35),@(60),@(150),@(80)];
NSArray *ys = @[@(100),@(35),@(40),@(200),@(300)];

CGPoint previousCenter = CGPointZero;
for (NSUInteger i = 0; i < [xs count]; i++)
{
    CGPoint start = previousCenter;
    CGPoint end = CGPointMake([xs[i]floatValue], [ys[i]floatValue]);
    if (i == 0) {
        CGContextMoveToPoint(ctx, start.x, start.y);
    }
    
    CGContextAddLineToPoint(ctx, end.x, end.y);
    
    previousCenter = end;
}

CGContextDrawPath(ctx, kCGPathStroke);

UIView是写在 drawRect:(CGRect)rect里面
CALayer是写在 drawInContext:(CGContextRef)ctx里面

PHPzPHPz2713 天前335

全部回复(2)我来回复

  • 天蓬老师

    天蓬老师2017-04-18 09:29:50

    你可以换成CAshapleLayer;下面的是iphone6模拟器放大到100效果的图片代码

    UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:rect];
    NSArray *xs = @[@(10),@(35),@(60),@(150),@(80)];
    NSArray *ys = @[@(100),@(35),@(40),@(200),@(300)];
    
    CGPoint previousCenter = CGPointZero;
    for (NSUInteger i = 0; i < [xs count]; i++)
    {
        CGPoint start = previousCenter;
        CGPoint end = CGPointMake([xs[i]floatValue], [ys[i]floatValue]);
        if (i == 0) {
            [circlePath moveToPoint:start];
        }
        
        [circlePath addLineToPoint:end];
        
        previousCenter = end;
    }
    
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = circlePath.CGPath;
    layer.strokeColor = [UIColor redColor].CGColor;
    layer.lineWidth = 10;
    layer.lineJoin = @"round";
    [self.layer addSublayer:layer];

    回复
    0
  • 巴扎黑

    巴扎黑2017-04-18 09:29:50

    layer.contentsScale = [UIScreen mainScreen].scale;

    在你的DrawLayer上设置上面的值。

    /* Defines the scale factor applied to the contents of the layer. If
     * the physical size of the contents is '(w, h)' then the logical size
     * (i.e. for contentsGravity calculations) is defined as '(w /
     * contentsScale, h / contentsScale)'. Applies to both images provided
     * explicitly and content provided via -drawInContext: (i.e. if
     * contentsScale is two -drawInContext: will draw into a buffer twice
     * as large as the layer bounds). Defaults to one. Animatable. */
    
    @property CGFloat contentsScale
      __OSX_AVAILABLE_STARTING (__MAC_10_7, __IPHONE_4_0);

    这个属性的默认值是1.

    参考代码:

    sublayer

    DrawLayer *layer = [DrawLayer layer];
    layer.contentsScale = [UIScreen mainScreen].scale;
    layer.frame = layerView.bounds;
    [layer setNeedsDisplay];
    [layerView.layer addSublayer:layer];

    layer

    @implementation TestView
    + (Class)layerClass
    {
        return [DrawLayer class];
    }
    @end
    TestView *layerView = [[TestView alloc] initWithFrame:CGRectMake(0, 0, 500, 300)];
    layerView.layer.contentsScale = [UIScreen mainScreen].scale;
    [layerView.layer setNeedsDisplay];
    [self.view addSubview:layerView];

    回复
    0
  • 取消回复