André Fratelli
André Fratelli

Reputation: 6068

Drawing anti-aliased line

I'm drawing a line on the screen which includes diagonal lines which in turn are drawing like this:

enter image description here

Notice how it doesn't look smooth at all. I've read a few articles on this and it would seem this looks the one closer to the issue I'm having, but the solution is not working for me.

Here's how I setup the layer:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Instantiate the navigation line view
    CGRect navLineFrame = CGRectMake(0.0f, 120.0f, self.view.frame.size.width, 15.0f);
    self.navigationLineView = [[HyNavigationLineView alloc] initWithFrame:navLineFrame];

    // Make it's background transparent
    self.navigationLineView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.0f];
    self.navigationLineView.opaque = NO;

    HyNavigationLineLayer * layer = [[HyNavigationLineLayer alloc] init];
    layer.shouldRasterize = YES;
    layer.rasterizationScale = [UIScreen mainScreen].scale;
    layer.contentsScale = [[UIScreen mainScreen] scale];
    layer.needsDisplayOnBoundsChange = YES;

    [[self.navigationLineView layer] addSublayer:layer];
    [self.view addSubview:self.navigationLineView];
    [self.navigationLineView.layer setNeedsDisplay];
}

Here's how I'm drawing in the layer:

- (void)drawInContext:(CGContextRef)ctx
{
    CGFloat bottomInset = 1.0f / [[UIScreen mainScreen] scale] * 2.0f;

    CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);
    CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);

    GLfloat padding = kHyNavigationLineViewPadding * 4.0f;
    GLfloat searchSpace = self.frame.size.width - padding - kHyNavigationLineViewPointerSize * 2.0f;
    GLfloat x = kHyNavigationLineViewPadding * 2.0f + searchSpace * self.offset;

    CGContextSetLineWidth(ctx, 2.0f);
    CGContextMoveToPoint(ctx, kHyNavigationLineViewPadding, 0.0f);
    CGContextAddLineToPoint(ctx, x, bottomInset);
    CGContextAddLineToPoint(ctx, x + kHyNavigationLineViewPointerSize, self.frame.size.height);
    CGContextAddLineToPoint(ctx, x + kHyNavigationLineViewPointerSize * 2.0f, bottomInset);
    CGContextAddLineToPoint(ctx, self.frame.size.width - kHyNavigationLineViewPadding, 0.0f);

    // Draw
    CGContextStrokePath(ctx);
}

Any hints on how to solve this?

Edit: forgot to mention the reason I was drawing in the layer in the first place: I need to animate a property which causes this line to animate was well, so drawing in drawRect doesn't work.

Upvotes: 2

Views: 1223

Answers (1)

William Chen
William Chen

Reputation: 278

Instead of using quartz to render the code, you can use UIBezierPath to render instead:

UIBezierPath* path = [UIBezierPath bezierPath];

[[UIColor whiteColor] setStroke];

GLfloat padding = kHyNavigationLineViewPadding * 4.0f;
GLfloat searchSpace = self.frame.size.width - padding - kHyNavigationLineViewPointerSize * 2.0f;
GLfloat x = kHyNavigationLineViewPadding * 2.0f + searchSpace * self.offset;

path.lineWidth = 2.0;
[path moveToPoint:CGPointMake(kHyNavigationLineViewPadding, 0)];
[path addLineToPoint:CGPointMake(x, bottomInset)];
[path addLineToPoint:CGPointMake(x + kHyNavigationLineViewPointerSize, self.frame.size.height)];
[path addLineToPoint:CGPointMake(x + kHyNavigationLineViewPointerSize * 2.0f, bottomInset)];
[path addLineToPoint:CGPointMake(self.frame.size.width - kHyNavigationLineViewPadding, 0.0f)];

[path stroke];

Upvotes: 2

Related Questions