Применение инсульта к округлению прямого в основной графике
-
24-09-2019 - |
Вопрос
У меня есть градиент, который округлые углы, которые я использую для пользовательского фона UiableViewCell. Я пытаюсь применить удар на путь, но не может это сделать, и не вижу, куда я иду не так.
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny ;
maxx = maxx - 1;
maxy = maxy - 1;
CGContextMoveToPoint(c, minx, miny);
CGContextAddArcToPoint(c, minx, maxy, midx, maxy, kDefaultMargin);
CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, kDefaultMargin);
CGContextAddLineToPoint(c, maxx, miny);
CGContextAddLineToPoint(c, minx, miny);
// Fill and stroke the path
CGContextClip(c);
CGContextStrokePath(c);
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat mycomponents[8] = TABLE_CELL_BACKGROUND;
CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef myGradient = CGGradientCreateWithColorComponents(myColorspace, mycomponents, locations, 2);
CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
CGGradientRelease(myGradient);
CGColorSpaceRelease(myColorspace);
Этот код раундут прямоугольник вправо и применяет градиент, но не включает строку. Где моя ошибка?
РЕДАКТИРОВАТЬ:Согласно рекомендациям Subw, я изменил код:
CGContextRef c = UIGraphicsGetCurrentContext();
CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef myGradient = nil;
CGFloat components[8] = TABLE_CELL_BACKGROUND;
CGContextSetFillColorWithColor(c, [[UIColor redColor] CGColor]);
CGContextSetStrokeColorWithColor(c, [[UAColor redColor] CGColor]);
CGContextSetLineWidth(c, 2);
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny ;
maxx = maxx - 1;
maxy = maxy - 1;
CGContextMoveToPoint(c, minx, miny);
CGContextAddArcToPoint(c, minx, maxy, midx, maxy, kDefaultMargin);
CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, kDefaultMargin);
CGContextAddLineToPoint(c, maxx, miny);
CGContextAddLineToPoint(c, minx, miny);
// Fill and stroke the path
CGContextSaveGState(c);
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);
CGContextStrokePath(c);
Но прямо выглядит, как это ...
Text Text http://grab.by/2714.
... без границы. Если я изменим CGContextStrokePath(c)
быть CGContextStrokeRect(c, rect)
, инсульт появляется (я сделал это красным для разъяснения). Но каким-то образом, когда поглаживая путь, я не получаю никакого удара :(
Решение
Отвечая на ваш пересмотренный код, я цитирую документацию:
В отличие от текущего пути, текущий путь клиппирования является частью графического состояния. Поэтому, чтобы повторно увеличить покрашенную область, восстановив путь отсечения к предыдущему состоянию, вы должны сохранить графическое состояние перед закреплением и восстановлением графического состояния после завершения любого обрезанного чертежа.
После определения нового пути клиппирования функция сбрасывает текущий путь контекста к пустому пути.
Итак, текущий путь чертежа нет Часть графического состояния. Так вот вот что вы делаете:
- Создать путь рисования
- Сохранить GState.
- Добавить текущий путь рисования к обтравочному контуру; Очистить текущий путь рисования
- Нарисуйте градиент
- Восстановить GState (предыдущий путь клиппирования восстановлен; путь рисования остается пустым)
- Ничего не ходить
Решение состоит в том, чтобы нарисовать путь к объекту CGPath, затем добавьте его в качестве текущего пути как перед отсечением (после сохранения GSTATE) и перед поглаживанием.
Вы также должны решить, хотите ли вы это быть внешним ходом, внутренним ходом или центрированным ходом. Для центрированного инсульта, инсульт, не зарекомендовавшись. Для внутреннего хода, ход при обрезании. Для наружного хода обратный путь, затем клип, затем ход. Вы захотите удвоить ширину вашей линии для обоих последних двух форм, поскольку вы будете разрывать половину хода.
Если я изменим
CGContextStrokePath(c)
бытьCGContextStrokeRect(c, rect)
, инсульт появляется.
Потому что эта функция добавляет путь этого прямоугольника к текущему пути чертежа перед поглаживанием.
Другие советы
Не уверен, но, возможно, вы рисуете градиент на ходу?
Вы либо рисуете градиент по инсульту и / или отсечив область, которую вы поглаживаете.
Я думаю, что следующее может работать лучше:
CGContextSaveGState(c);
CGContextClip(c);
//gradient drawing stuff
CGContextRestoreGState(c);
CGContextStrokePath(c);
Конечно, вам также нужно правильно установить цвет инсульта и ширина.