2011-06-05 15 views
14

Quando si imposta la proprietà di trasformazione del mio CALayer con un CATransform3DRotate, il livello viene ruotato correttamente. Tuttavia, i bordi del livello sono frastagliati e non anti-alias. Ho letto un paio di messaggi sul tema:Bordi diagonali anti-alias di CALayer

iPhone: CALayer + rotate in 3D + antialias?

iPhone - Jagged Edges when applying perspective to CALayer

Ho cercato di integrare i loro consigli impostando le seguenti proprietà sul mio strato diagonale

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 Ho anche scavalcato drawLayer: inContext: metodo del mio livello diagonale per garantire l'anti-aliasing:

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

Cosa mi manca?

risposta

14

Ho appena fatto un post su questo per le immagini. Forse aiuterà.

Ho trovato alcuni trucchi che aiutano e impostare solo un bordo non ha fatto quello che pensavo. Quello che puoi fare è impostare alcune impostazioni per facilitare l'interpolazione, la rasterizzazione e la rasterizzazione della scala.

vedere se qualcosa da questo codice consente:

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; 

Ho alcuni esempi postato here

+0

Fantastico! Ottimo post. – tassock

+5

C'è un'alternativa massicciamente migliore su 7.0 e successivi. http://stackoverflow.com/questions/6245276/anti-alias-diagonal-edges-of-calayer/19443644#19443644 – cbowns

29

Come di iOS7, questo è ora finalmente possibile su una base per-layer e senza alcun hack brutto come pixel trasparenti o soluzioni alternative come rasterizzazione:

layer.allowsEdgeAntialiasing = YES;

interessante notare che questo non è copertura edita dalla documentazione ufficiale di CALayer, ma è sicuramente una API pubblica. Vedi lo iOS7 API diffs e l'eccellente articolo di Peter Steinberger su Hidden Gems and Workarounds in iOS7.

+0

Questa è la mia nuova API CA preferita. – cbowns

+0

Questo non è possibile su OSX :( 'allowEdgeAntialiasing' non è disponibile. Come lo faresti in OSX? –