Сглаживание закругленного обводки в Core Graphics - PullRequest
4 голосов
/ 02 февраля 2010

Я создаю свои собственные UITableViewCells с градиентным фоном. Я проработал всю логику и рисование, но одну вещь, которую я хочу исправить, - это "мелкость" по углам моей пользовательской ячейки:

альтернативный текст http://grab.by/27SM

Если увеличить углы, вы увидите, о чем я говорю. Вот код, который я использую для генерации ячейки:

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);

Что я могу сделать, чтобы сгладить края, сохраняя одинаковую толщину края во всех ячейках?

Ответы [ 2 ]

7 голосов
/ 02 февраля 2010

Ваша ширина линии установлена ​​на 2 точки. Происходит то, что ваш код вычисляет ограничивающий прямоугольник, не понимая ширину линии. В результате для каждого прямого сегмента вашей фигуры видна только половина ширины обводки. На дуге видна полная ширина хода.

Вот соответствующий фрагмент кода из моего приложения, Funversation, для рисования игральных карт со скругленными углами, аналогично тому, что у вас есть.

CGRect rect = [self bounds];
rect.size.width -= lineWidth;
rect.size.height -= lineWidth;
rect.origin.x += lineWidth / 2.0;
rect.origin.y += lineWidth / 2.0;

Добавьте это перед вашими вычислениями для minx, midx, maxx и т. Д., И штрихи для вашей фигуры должны быть одинаковыми.

1 голос
/ 02 февраля 2010

Другим способом обеспечения согласованности обводки является перемещение вызовов AddPath и StrokePath выше вызова RestoreGState, то есть обводки при обрезании.

Для поистине обводки шириной 2 пт с этим решением просто удвойте ширину линии, которую вы поместили в графическое состояние (т.е. установите его на 4 пт), так как половина будет вырезана.

...