2010-09-07 4 views
4

J'essaie d'ajouter une petite ligne rouge au bas de mon UIView.UIView drawRect tracer des lignes de largeur incorrecte

Je souhaite que la ligne soit une ligne 1px.

Quelqu'un peut-il me dire pourquoi le code suivant:

- (void)drawRect:(CGRect)rect { 
CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
CGContextSaveGState(currentContext); 
CGContextSetRGBFillColor(currentContext, 0.0f, 0.0f, 0.0f, 1.0f); 
CGContextFillRect(currentContext, RECT(0, 0, rect.size.width, rect.size.height - 8)); 
CGContextSetLineWidth(currentContext, 1); 
CGContextSetRGBStrokeColor(currentContext, 1.0f, 0.0f, 0.0f, 1.0f); 
CGContextBeginPath(currentContext); 
CGContextMoveToPoint(currentContext, 0, rect.size.height - 7); 
CGContextAddLineToPoint(currentContext, rect.size.width, rect.size.height - 7); 
CGContextStrokePath(currentContext); 
CGContextRestoreGState(currentContext); 
} 

Dessine une ligne qui enjambe 2px en hauteur?

Répondre

13

Les coordonnées solidaires indiquent les endroits à mi-chemin entre pixels; c'est-à-dire, (0,0) est dans le coin supérieur gauche, ci-dessus et à gauche du pixel supérieur gauche; de même, (1,0) est entre les premier et second pixels; enfin, (0.5, 0.5) est au centre du pixel supérieur gauche.

Selon the documentation for CGContextSetLineWidth, "lorsque la ligne est parcourue, la ligne chevauche le chemin, avec la moitié de la largeur totale de chaque côté." Ainsi, si le chemin se trouve précisément entre les pixels, la ligne sera parcourue à moitié sur une ligne de pixels, la moitié sur l'autre. Par conséquent, pour obtenir une ligne de pixels nette, vous devez décaler vos coordonnées d'un demi-pixel: pour la coordonnée x, utilisez rect.size.height - 7.5 au lieu de - 7. Par ailleurs, lorsque vous dessinez des rectangles, il est pratique d'utiliser CGRectInset(rect, 0.5, 0.5) pour y parvenir.

+0

+1 C'est un comportement si étrange, mais ça fonctionne vraiment. J'étais vraiment perplexe par celui-ci. – bentford

1

Utilisez-vous un iPhone 4? L'iPhone 4 utilise un système de coordonnées avec un facteur d'échelle de 2. Donc, vous devez définir la largeur de la ligne à 0,5 afin d'obtenir ce que vous voulez.

(Le système de coordonnées est réglé de cette façon, le même code produit la même sortie pour tous les modèles.)

+2

Une ligne d'un pixel d'épaisseur sur un affichage normal * doit avoir * deux pixels d'épaisseur sur un écran Retina. –

0

Les lignes sont par défaut dessinées anti-aliasées (sauf si vous configurez autrement). Ainsi, toute ligne qui n'est pas strictement verticale ou horizontale et qui commence et se termine sur un pixel couvrira probablement partiellement plusieurs pixels dans certaines lignes et/ou colonnes, ce qui lui donne l'apparence d'une ligne grise plus large.

+0

Oui, les lignes ont l'air d'être anti-crénelées, mais quand je désactive l'antialiasing, elles ont toujours l'air de cette façon. – almosnow

Questions connexes