Применение инсульта к округлению прямого в основной графике

StackOverflow https://stackoverflow.com/questions/2177094

Вопрос

У меня есть градиент, который округлые углы, которые я использую для пользовательского фона 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);

Этот код раундут прямоугольник вправо и применяет градиент, но не включает строку. Где моя ошибка?

Alt Text http://grab.by/26ye.



РЕДАКТИРОВАТЬ:Согласно рекомендациям 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), инсульт появляется (я сделал это красным для разъяснения). Но каким-то образом, когда поглаживая путь, я не получаю никакого удара :(

Alt Text http://grab.by/27am.

Это было полезно?

Решение

Отвечая на ваш пересмотренный код, я цитирую документацию:

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

После определения нового пути клиппирования функция сбрасывает текущий путь контекста к пустому пути.

CGContextClip.

Итак, текущий путь чертежа нет Часть графического состояния. Так вот вот что вы делаете:

  1. Создать путь рисования
  2. Сохранить GState.
  3. Добавить текущий путь рисования к обтравочному контуру; Очистить текущий путь рисования
  4. Нарисуйте градиент
  5. Восстановить GState (предыдущий путь клиппирования восстановлен; путь рисования остается пустым)
  6. Ничего не ходить

Решение состоит в том, чтобы нарисовать путь к объекту CGPath, затем добавьте его в качестве текущего пути как перед отсечением (после сохранения GSTATE) и перед поглаживанием.

Вы также должны решить, хотите ли вы это быть внешним ходом, внутренним ходом или центрированным ходом. Для центрированного инсульта, инсульт, не зарекомендовавшись. Для внутреннего хода, ход при обрезании. Для наружного хода обратный путь, затем клип, затем ход. Вы захотите удвоить ширину вашей линии для обоих последних двух форм, поскольку вы будете разрывать половину хода.

Если я изменим CGContextStrokePath(c) быть CGContextStrokeRect(c, rect), инсульт появляется.

Потому что эта функция добавляет путь этого прямоугольника к текущему пути чертежа перед поглаживанием.

Другие советы

Не уверен, но, возможно, вы рисуете градиент на ходу?

Вы либо рисуете градиент по инсульту и / или отсечив область, которую вы поглаживаете.

Я думаю, что следующее может работать лучше:

CGContextSaveGState(c);
CGContextClip(c);

//gradient drawing stuff

CGContextRestoreGState(c);
CGContextStrokePath(c);

Конечно, вам также нужно правильно установить цвет инсульта и ширина.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top