2009-09-21 8 views
5

Ich habe eine benutzerdefinierte UIView, die mit seiner -[drawRect:] Methode gezeichnet wird.Weird-Anti-Aliasing in benutzerdefinierten Ansicht

Das Problem ist, dass das Anti-Aliasing sehr seltsam wirkt, da schwarze Linien horizontale oder vertikale Linien sehr verschwommen gezeichnet werden.

Wenn ich Anti-Aliasing mit CGContextSetAllowsAntialiasing deaktivieren, wird alles wie erwartet gezeichnet.

Anti-Aliasing:
alt text http://dustlab.com/stuff/antialias.png

Kein Anti-Aliasing (das wie das erwartete Ergebnis mit AA sieht):
alt text http://dustlab.com/stuff/no_antialias.png

Die Linienbreite ist exakt 1 und alle Koordinaten sind Integralwerte .

Das gleiche passiert, wenn ich ein Rechteck mit CGContextStrokeRect zeichne, aber nicht, wenn ich genau das gleiche CGRect mit UIRectStroke zeichne.

Antwort

10

Da ein Hub auf beiden Seiten gleich viel erweitert, eine Linie von einer Pixelbreite muss nicht auf einer ganzzahligen Koordinate platziert werden, sondern bei 0,5 Pixel Offset.

berechnen richtigen Koordinaten für Konturlinien wie folgt aus:

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

BTW: Sie werfen Ihre Werte nicht in int und Rückseite des Dezimalteil zu schweben, um loszuwerden. Dafür gibt es in C eine Funktion namens floor.

+2

Zusätzlich bietet Apple einige nützliche Tipps und Beispielcode im Abschnitt "Doing Pixel-Exact Drawing" des Cocoa Drawing Guide: http://developer.apple.com/mac/library/documentation/Cocoa/ Conceptual/CocoaDrawingGuide/Transforms/Transforms.html # // Apple_ref/doc/uid/TP40003290-CH204-BCICIJAJ –

+0

Hier ist ein einfacher Weg, ohne überhaupt Code zu vermeiden http://www.techpaa.com/2012/06/avoiding -view-edge-antialiasing.html – ShivaPrasad

+0

@jeeva 'UIViewEdgeAntialiasing' ist nur für Kanten von Ebenen. Die Frage bezieht sich auf in Quartz gezeichnete Linien. Die Quartzzeichnung wird nicht von 'UIViewEdgeAntialiasing' beeinflusst. –

0

In Ihren View-Frames haben Sie wahrscheinlich Float-Werte, die keine Ganzzahlen sind. Während der Rahmen präzise genug ist, um Bruchteile eines Pixels (float) zu tun, werden Sie Unschärfen, wenn Sie zu einem

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