2012-05-27 13 views
12

ja rysując ścieżkę w moim realizacji drawRect na UIView z:Rysunek 1 piksel szerokości ścieżki w iOS

CGContextSetLineWidth(context, 0.5); 
CGContextStrokePath(context); 

anty-aliasing na mojej CGContext, ja nie potrafię rysować linie 1 px .

on

starałem toczenia antialiasing mecz:

CGContextSetShouldAntialias(context, NO); 

ale potem moje rogi wyglądają straszne:

off

Jak utrzymać antialiasing na ale zatrzymać ten pod- pixel bluring linii 1 piksela?

+0

rdzeń graficzny nie używa pikseli, ale punkty. – uchuugaka

Odpowiedz

23

Po narysowaniu linii w systemie iOS określa się współrzędne nieskończenie wąskiej linii. Narysowana linia rozszerzy się następnie na obie strony tej linii o połowę szerokości obrysu.

Jeśli twoja nieskończenie wąska linia ma współrzędne całkowite i jest pozioma lub pionowa, narysowana linia będzie miała szerokość dwóch pikseli i szary zamiast jednego piksela i czarny (z wygładzaniem). Bez wygładzania linia będzie lekko przesunięta, ale kąty wyglądają brzydko.

Aby rozwiązać problem, użyj współrzędnych w środku piksela (na przykład 200,5/170,5) i włącz wygładzanie.

+0

Myślałem, że próbowałem tego wcześniej i zadziałało, ale z jakiegoś powodu to nie działa teraz i nie mogę zrozumieć, dlaczego ... – chrism

+7

Duh! Przepraszam, tak naprawdę nie myślałem - wyświetlacze Retina oczywiście oznaczają, że środek piksela to 0,25, a nie 50 w skalowanej przestrzeni, którą rysujesz. – chrism

+1

@chryzm +1, który nie był "duh!" dla mnie, nie sądzę, żebym kiedykolwiek to odkrył, gdybym nie natknął się na to w ten sposób ... – Mazyod

10
- (void)drawRect:(CGRect)rect 
{ 
    [super drawRect:rect]; 

    CGFloat inset = 0.5/[[UIScreen mainScreen] scale]; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); 
    // draw 
    CGContextSetLineWidth(context, inset); 
    CGContextSetStrokeColorWithColor(context, _lineColor.CGColor); 
    CGContextMoveToPoint(context, inset, 0); 
    CGContextAddLineToPoint(context, inset, CGRectGetHeight(rect)); 
    CGContextStrokePath(context); 
    CGContextRestoreGState(context); 
} 
+0

Co to jest 'WKCommonUtil' co? –

+0

@ AndréFratelli prawdopodobnie trzeci framework do wykrywania urządzeń siatkówki. –

+0

@ AndréFratelli, jest to klasa użytkowa wykonana przeze mnie do testowania, czy urządzenie jest siatkówką. – Chengjiong

0

można przetłumaczyć cały kontekst poprzez:

CGContextSaveGState(context); 
CGFloat translation = 0.5f/[[UIScreen mainScreen] scale]; 
CGContextTranslateCTM(context, translation, translation); 
... your drawing here ... 
CGContextRestoreGState(context); 

To wszystko!

0

Jedynym rozwiązaniem, że pracował dla mnie było to:

override func drawRect(rect: CGRect) { 

    let context = UIGraphicsGetCurrentContext() 

    CGContextSetLineWidth(context, 0.5) 

    CGContextMoveToPoint(context, 0.0, 0.25) 
    CGContextAddLineToPoint(context, rect.size.width, 0.25) 

    CGContextSetStrokeColorWithColor(context, UIColor.blackColor().CGColor) 
    CGContextStrokePath(context) 
}