2012-05-27 9 views
12

Estoy dibujando un camino en mi aplicación drawRect en un UIView con:dibujo amplios caminos de 1 píxel en iOS

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

Con el suavizado en mi CGContext, me parece que no puede dibujar líneas 1 px .

on

me ha intentado girarlo apagado con antialiasing:

CGContextSetShouldAntialias(context, NO); 

pero luego mis esquinas muy mal aspecto:

off

¿Cómo puedo evitar el antialiasing, pero dejan de esta sub pixel bluring de líneas de 1 píxel?

+0

núcleo de gráficos no utiliza píxeles, pero puntos. – uchuugaka

Respuesta

23

Cuando dibuja una línea en iOS, especifica las coordenadas de una línea infinitamente estrecha. La línea dibujada se extenderá luego a ambos lados de esa línea a la mitad del ancho del trazo.

Si su línea infinitamente estrecha tiene coordenadas enteras y es horizontal o vertical, la línea dibujada tendrá dos píxeles de ancho y gris en lugar de un píxel de ancho y negro (con anti-aliasing). Sin anti-aliasing, la línea se moverá ligeramente pero las esquinas se ven feas.

Para resolverlo, utilice las coordenadas en el medio de un píxel (por ejemplo, 200.5/170.5) y active el suavizado.

+0

Pensé que había intentado esto antes y funcionó, pero por alguna razón no funciona ahora, y no puedo entender por qué ... – chrism

+7

¡Duh! lo siento, realmente no estaba pensando - Las pantallas de Retina obviamente significan que la mitad de un píxel es .25, no .50 en el espacio escalado que dibujas. – chrism

+1

@chrism +1 que no era un "duh!" para mí, no creo haberlo descubierto si no me hubiese encontrado así ... – 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

¿Qué es eso de 'WKCommonUtil'? –

+0

@ AndréFratelli probablemente un tercer marco para detectar dispositivos retina. –

+0

@ AndréFratelli, esta es una clase de utilidad hecha por mí mismo para probar si el dispositivo está retina. – Chengjiong

0

Puede traducir todo contexto a través de:

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

Eso es todo!

0

La única solución que funcionó para mí fue la siguiente:

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) 
} 
Cuestiones relacionadas