Для всех, кто интересуется, как нарисовать внутреннюю тень с помощью Core Graphics в соответствии с предложением Costique, тогда вот как: (на iOS настройте по мере необходимости)
В вашем методе drawRect: ...
CGRect bounds = [self bounds];
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat radius = 0.5f * CGRectGetHeight(bounds);
CGMutablePathRef visiblePath = CGPathCreateMutable();
CGRect innerRect = CGRectInset(bounds, radius, radius);
CGPathMoveToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y);
CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x + innerRect.size.width, bounds.origin.y);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y, bounds.origin.x + bounds.size.width, innerRect.origin.y, radius);
CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, innerRect.origin.y + innerRect.size.height);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, innerRect.origin.x + innerRect.size.width, bounds.origin.y + bounds.size.height, radius);
CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y + bounds.size.height);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x, bounds.origin.y + bounds.size.height, bounds.origin.x, innerRect.origin.y + innerRect.size.height, radius);
CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x, innerRect.origin.y);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x, bounds.origin.y, innerRect.origin.x, bounds.origin.y, radius);
CGPathCloseSubpath(visiblePath);
UIColor *aColor = [UIColor redColor];
[aColor setFill];
CGContextAddPath(context, visiblePath);
CGContextFillPath(context);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectInset(bounds, -42, -42));
CGPathAddPath(path, NULL, visiblePath);
CGPathCloseSubpath(path);
CGContextAddPath(context, visiblePath);
CGContextClip(context);
aColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f];
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 3.0f, [aColor CGColor]);
[aColor setFill];
CGContextSaveGState(context);
CGContextAddPath(context, path);
CGContextEOFillPath(context);
CGPathRelease(path);
CGPathRelease(visiblePath);
Итак, по сути, это следующие шаги:
- Создай свой путь
- Задайте нужный цвет заливки, добавьте этот путь в контекст и заполните контекст
- Теперь создайте прямоугольник большего размера, ограничивающий видимый путь. Прежде чем закрыть этот путь, добавьте видимый путь. Затем закройте контур, чтобы создать фигуру, из которой вычтена видимая линия. Возможно, вы захотите изучить методы заполнения (ненулевое обмотка четного / нечетного) в зависимости от того, как вы создали эти пути. По сути, чтобы заставить подпути «вычитаться», когда вы складываете их вместе, вам нужно нарисовать их (или, скорее, построить) в противоположных направлениях, одно по часовой стрелке, а другое - против часовой стрелки.
- Затем вам нужно установить видимый путь в качестве обтравочного контура в контексте, чтобы вы не рисовали на экране ничего за его пределами.
- Затем настройте тень в контексте, включая смещение, размытие и цвет.
- Затем заполните большую форму отверстием. Цвет не имеет значения, потому что, если вы все сделали правильно, вы не увидите этого цвета, только тень.