2010-11-19 1 views
8

Ho un UIView e al suo interno ho tracciato una linea utilizzando Core Graphics sovrascrivendo drawRect. Questa vista contiene anche una sottoview che disegna anche una linea. Tuttavia, mentre entrambe le viste stanno usando più o meno lo stesso codice (a scopo di test, almeno), le linee tracciate su di essi non appaiono lo stesso:iPhone Core Graphics linea tratteggiata più spessa per subview

Image problem

Come si può vedere - la linea tratteggiata al la parte superiore è visibilmente più spessa di quella inferiore e non ho idea del perché. Di seguito è riportato il codice utilizzato dai due UIViews nei loro metodi drawRect. Se hai qualche idea del perché questo sta accadendo, apprezzerei il tuo aiuto e i tuoi consigli!

Prima Vista:

CGContextRef context = UIGraphicsGetCurrentContext(); 

CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]); 

CGFloat dashes[] = {1,1}; 

CGContextSetLineDash(context, 0.0, dashes, 2); 
CGContextSetLineWidth(context, 0.6); 

CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMaxY(rect)); 
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMaxY(rect)); 

CGContextStrokePath(context); 

SubUIView *view = [[SubUIView alloc] initWithFrame:rect]; 
[self addSubview:view]; 
[view release]; 

La vista è sicuramente solo in fase di elaborazione una volta. Apprezzo che drawRect non sia il posto migliore per aggiungere una sottoview ma il problema rimane anche se è stato aggiunto nel metodo principale initWithFrame.

Seconda Vista:

CGContextRef context = UIGraphicsGetCurrentContext(); 

CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]); 

CGFloat dashes[] = {1,1}; 

CGContextSetLineDash(context, 0.0, dashes, 2); 
CGContextSetLineWidth(context, 0.6); 

CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect)); 
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMidY(rect)); 

CGContextStrokePath(context); 
+1

Perché stai aggiungendo una sottoview in 'drawRect:'? – jer

+0

@jer: ha importanza? Posso aggiungere la sottoview da un altro metodo come 'initWithFrame', ma c'è ancora una differenza nello spessore della linea. A meno che non intenda aggiungere sottoview a una vista che "disegna" su se stessa e quindi il problema (?), Ma non l'ho letto da nessuna parte ... ancora. – JoeR

+1

@JoeR, sì può essere importante - aggiungi sottoview ogni volta che la tua vista si disegna in modo che tu possa terminare con più sottoview identiche poste l'una sull'altra - e questo potrebbe causare linee di sottofondo più spesse man mano che venivano disegnate più volte – Vladimir

risposta

6

Potrebbe essere il risultato di anti-aliasing se il rect non cade su interi. È possibile disabilitare l'anti-aliasing con CGContextSetShouldAntialias(context, NO). Penso che ci sia anche una funzione per rendere integrale un rect, ma non riesco a ricordare quale sia.

+0

Grazie! Questo l'ha risolto! Suppongo che il fatto che nessuna riga fosse bianca come specificato chiamando "CGContextSetStrokeColorWithColor" avrebbe dovuto essere un indizio del fatto che alcuni anti-aliasing stavano accadendo. Mi chiedo * perché * questo è accaduto nella sottoview e non nella vista principale, ma per ora sarò solo grato sta funzionando! – JoeR

+3

È CGRectIntegral() – nielsbot

-2

Innanzitutto, è necessario risolvere il problema del codice di disegno che è WET *. Dici che lo stai facendo "a scopo di test", ma in realtà questo rende i test più difficili, dal momento che devi cambiare entrambe le parti di codice e/o tenere dritta su quale versione stai lavorando. Il caso peggiore è quando modifichi entrambi i pezzi di codice in modi diversi e devi unirli a mano.

Direi spostare il codice tratteggiato nella sottoview, aggiungere proprietà per qualsiasi cosa che i due pezzi di codice devono fare in modo diverso, e creare due sottoview (e non in drawRect: -seriously).

Per quanto riguarda il problema reale: Beh, non vedo un'immagine grande, vedo un'immagine minuscola, e posso solo supporre che la maggiore audacia della linea superiore rispetto a quella della linea inferiore significa che la parte superiore la linea è più spessa.

A proposito, lo rect non è necessariamente il limite dell'immagine. Non dare per scontato che lo sia, o otterrai un disegno funky quando non lo è. Supponiamo che sia una parte dei limiti - forse, ma forse no, l'intera cosa. Quando intendi [self bounds], ad esempio [self bounds].

Il problema è molto probabilmente la differenza tra CGRectGetMidY([self bounds]) e CGRectGetMaxY([self bounds]). Uno include una frazione che divide un pixel, mentre l'altro è un multiplo di un pixel o vicino ad esso. (Non necessariamente un multiplo di 1-su un Retina Display, 1 pt = 2 pixel, quindi 1 pixel = 0,5 pt.) Prova a pavimentare entrambi i numeri e, opzionalmente, aggiungendo 0.5, e vedi come preferisci.

Non c'è modo di farlo funzionare perfettamente con una larghezza della linea di 0,6 punti. Semplicemente non c'è un numero intero di pixel che funzioni. Tutto quello che puoi fare è capire cosa è meglio e farlo.

* Scritto anche altrove, il contrario di ASCIUGAMANO.

+0

Grazie per l'input. Ho scambiato la grande immagine quando ho scritto la domanda, visto che il piccolo sembrava fare il lavoro. http://i.imgur.com/KalTm.png - se questo aiuta. Ad ogni modo, ottengo il problema con la dimensione in punti che sto usando, l'ho aumentato a 1.0 ma anche in questo caso si verifica lo stesso problema. Disattivare l'anti alias fa il trucco come per la risposta accettata. – JoeR