2009-09-21 9 views
5

Ho un personalizzato UIView che viene disegnato utilizzando il suo metodo -[drawRect:].Strano anti-aliasing in vista personalizzata

Il problema è che gli atti di anti-aliasing molto strani come linee nere linee orizzontali o verticali sono disegnati molto sfocata.

Se rendo invalido anti-aliasing con CGContextSetAllowsAntialiasing, tutto è disegnato come previsto.

anti-aliasing:
alt text http://dustlab.com/stuff/antialias.png

senza anti-alias (che sembra il risultato previsto con AA):
alt text http://dustlab.com/stuff/no_antialias.png

La larghezza della linea è esattamente 1, e tutte le coordinate sono valori interi .

Lo stesso accade se disegno un rettangolo utilizzando CGContextStrokeRect, ma non se disegno esattamente lo stesso CGRect con UIRectStroke.

risposta

10

Dal momento che un ictus si espande quantità uguali su entrambi i lati, una linea di larghezza di un pixel non è possibile posizionare su una coordinata intera, ma con offset di 0,5 pixel.

calcolare le coordinate corrette per linee tratteggiate come questo:

CGPoint pos = CGPointMake(floorf(pos.x) + 0.5f, floorf(pos.y) + 0.5f); 

BTW: non espressi i valori a int e di nuovo a galleggiare per sbarazzarsi della parte decimale. C'è una funzione per questo in C chiamato floor.

+2

Oltre a ciò, Apple fornisce alcuni suggerimenti e codice di esempio nella sezione "Esecuzione di disegni con pixel" della Guida al disegno del cacao: http://developer.apple.com/mac/library/documentation/Cocoa/ concettuale/CocoaDrawingGuide/Transforms/Transforms.html # // apple_ref/doc/uid/TP40003290-CH204-BCICIJAJ –

+0

qui è un modo semplice per evitare senza alcun codice affatto http://www.techpaa.com/2012/06/avoiding -view-edge-antialiasing.html – ShivaPrasad

+0

@jeeva 'UIViewEdgeAntialiasing' è solo per i bordi dei livelli. La domanda riguarda le linee tracciate in Quarzo. Il disegno al quarzo non è influenzato da 'UIViewEdgeAntialiasing'. –

0

nelle cornici vista, probabilmente hanno valori float che non sono numeri interi. Mentre i telai sono sufficientemente precisi per fare le frazioni di un pixel (float), si ottiene una macchia sfocata a meno che non si esegue il cast a un int

CGRect frame = CGRectMake((int)self.frame.bounds..., (int)...., (int)...., (int)....);