14

When I set the transform property of my CALayer with a CATransform3DRotate, the layer is properly rotated. However, the edges of the layer are jagged and not anti-aliased. I've read a couple posts on the subject:

iPhone: CALayer + rotate in 3D + antialias?

iPhone - Jagged Edges when applying perspective to CALayer

I've tried to incorporate their advice by setting the following properties on my diagonal layer

CALayer* layer = myView.layer;
layer.shadowOpacity = 0.01;
layer.edgeAntialiasingMask = kCALayerTopEdge | kCALayerBottomEdge | kCALayerRightEdge | kCALayerLeftEdge;
layer.borderWidth = 1.0;
layer.borderColor = [UIColor clearColor].CGColor;
layer.backgroundColor = [UIColor greenColor].CGColor;

I've also overridden the drawLayer:inContext: method of my diagonal layer to ensure anti-aliasing:

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context
{
    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetShouldAntialias(context, true);
    CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
    CGContextFillRect(context, self.bounds);
}

What am I missing?

Community
  • 1
  • 1
tassock
  • 1,633
  • 1
  • 17
  • 32

2 Answers2

30

As of iOS7, this is now finally possible on a per-layer basis and without any ugly hacks like transparent pixels or workarounds like rasterization:

layer.allowsEdgeAntialiasing = YES;

Interestingly, this is not covered by the official CALayer documentation, but is definitely a public API. See the iOS7 API diffs and Peter Steinberger's great write-up on Hidden Gems and Workarounds in iOS7.

Daniel Rinser
  • 8,855
  • 4
  • 41
  • 39
15

I just did a post on this for images. Maybe it will help.

I found a few tricks that help and setting just a border did not do what I thought it would. What you can do is set a few settings to help with interpolation, rasterizing, and the rasterisationScale.

See if something from this code helps:

    UIImage * img =[UIImage imageWithData:[NSData dataWithContentsOfFile:[[[NSBundle mainBundle ] resourcePath ] stringByAppendingPathComponent:@"AliasImage.png" ] ] ];
CGRect imageRect = CGRectMake( 0 , 0 , img.size.width + 4 , img.size.height + 4 );
UIGraphicsBeginImageContext( imageRect.size );
[img drawInRect:CGRectMake( imageRect.origin.x + 2 , imageRect.origin.y + 2 , imageRect.size.width - 4 , imageRect.size.height - 4 ) ];
CGContextSetInterpolationQuality( UIGraphicsGetCurrentContext() , kCGInterpolationHigh );
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[aliasImage setImage:img ];

aliasImage.transform = CGAffineTransformScale(aliasImage.transform , 0.45 , 0.45 );
aliasImage.layer.shouldRasterize = YES;
aliasImage.layer.rasterizationScale = 0.45;
aliasImage.layer.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge;
aliasImage.clipsToBounds = NO;
aliasImage.layer.masksToBounds = NO;

I have some examples posted here

Dipen Panchasara
  • 13,480
  • 5
  • 47
  • 57
Designerd
  • 531
  • 5
  • 8
  • 5
    There's a massively better alternative on 7.0 and later. http://stackoverflow.com/questions/6245276/anti-alias-diagonal-edges-of-calayer/19443644#19443644 – cbowns Feb 28 '14 at 01:03