Levigare una corsa arrotondata nella grafica centrale
-
24-09-2019 - |
Domanda
Sto creando i miei uitableViewcells con uno sfondo a gradiente. Ho funzionato tutta la logica e il disegno, ma una cosa che voglio risolvere è la "grossa" intorno agli angoli della mia cella personalizzata:
Se ingrandisci gli angoli, puoi vedere di cosa sto parlando. Ecco il codice che utilizza per generare la cella:
CGContextRef c = UIGraphicsGetCurrentContext();
CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef myGradient = nil;
CGFloat components[8] = TABLE_CELL_BACKGROUND;
CGContextSetStrokeColorWithColor(c, [[UAColor colorWithWhite:0.7 alpha:1] CGColor]);
CGContextSetLineWidth(c, 2);
CGContextSetAllowsAntialiasing(c, YES);
CGContextSetShouldAntialias(c, YES);
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, minx, miny);
CGPathAddArcToPoint(path, NULL, minx, maxy, midx, maxy, kDefaultMargin);
CGPathAddArcToPoint(path, NULL, maxx, maxy, maxx, miny, kDefaultMargin);
CGPathAddLineToPoint(path, NULL, maxx, miny);
CGPathAddLineToPoint(path, NULL, minx, miny);
CGPathCloseSubpath(path);
// Fill and stroke the path
CGContextSaveGState(c);
CGContextAddPath(c, path);
CGContextClip(c);
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat mycomponents[8] = TABLE_CELL_BACKGROUND;
CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
myGradient = CGGradientCreateWithColorComponents(myColorspace, mycomponents, locations, 2);
CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
CGContextRestoreGState(c);
CGContextAddPath(c, path);
CGContextStrokePath(c);
Cosa posso fare per levigare i bordi mantenendo uno spessore del bordo costante su tutte le cellule?
Soluzione
La larghezza della tua linea è impostata su 2 punti. Quello che sta succedendo è che il tuo codice sta calcolando il tuo recupero di delimitazione senza comprendere la larghezza della linea. Il risultato è che per ogni segmento dritto della tua forma, è visibile solo la metà della larghezza della corsa. Sull'arco, la larghezza della corsa completa è visibile.
Ecco il segmento pertinente del codice dalla mia app, Funversation, per disegnare le carte da gioco con angoli arrotondati simili a quello che hai.
CGRect rect = [self bounds];
rect.size.width -= lineWidth;
rect.size.height -= lineWidth;
rect.origin.x += lineWidth / 2.0;
rect.origin.y += lineWidth / 2.0;
Aggiungilo prima del calcolo per Minx, Midx, Maxx, ecc. E i colpi per la tua forma dovrebbero essere uniformi.
Altri suggerimenti
L'altro modo per rendere coerente l'ictus sarebbe spostare l'addpath e la ictuspace richiamati sopra la chiamata di RestoregState, ovvero l'ictus mentre è tagliata.
Per una corsa veramente larga 2 pt con questa soluzione, è sufficiente raddoppiare la larghezza della linea che si mette nello stato grafico (cioè, impostala su 4 pt), poiché la metà di essa verrà tagliata.