Как с помощью iPhone SDK очистить углы за пределами закругленного прямоугольника?

Я пытаюсь реализовать собственное представление. В этом представлении должно отображаться изображение, окруженное серой прямоугольной рамкой с закругленными углами. Я могу добиться, чтобы изображение отображалось нормально, а также граница, однако, поскольку граница имеет закругленные углы, мне нужен способ очистить эти углы, чтобы они правильно отображали все, что находится за видом. Как я могу этого добиться?

Похоже, я мог бы использовать CGContextClearRect, но тогда разве мне не пришлось бы вызывать это несколько раз, восстанавливая область за пределами моего закругленного угла? Звучит слишком сложно.

Есть ли лучший способ создать это представление?

Вот мой текущий код:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw the image. This will completely fill the current rect.
    [image drawInRect:self.bounds];

    // Ensure we draw completely within our bounds instead of straddling it.
    CGRect rrect = self.bounds;
    rrect.size.height = rrect.size.height - 1.0;
    rrect.size.width = rrect.size.width - 1.0;
    rrect.origin.x = rrect.origin.x + (1.0 / 2);
    rrect.origin.y = rrect.origin.y + (1.0 / 2);

    CGFloat radius = 5.0;
    CGFloat minx = CGRectGetMinX(rrect);
    CGFloat midx = CGRectGetMidX(rrect);
    CGFloat maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect);
    CGFloat midy = CGRectGetMidY(rrect);
    CGFloat maxy = CGRectGetMaxY(rrect);

    // Draw the rounded rect border.
    CGContextSetRGBStrokeColor(context, 0.6, 0.6, 0.6, 1.0);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.0);
    CGContextSetLineWidth(context, 1.0);
    CGContextMoveToPoint(context, minx, midy);
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke);
}

person Sebastian Celis    schedule 14.04.2009    source источник


Ответы (2)


Добавьте прямоугольный контур с закругленными углами к обтравочному контуру перед рисованием изображения.

person Peter Hosey    schedule 14.04.2009
comment
Спасибо! Итак, CGContextClip, кажется, очищает текущий путь рисования. Означает ли это, что мне нужно дважды проследить один и тот же путь? Один раз обрезать, а один раз нарисовать? Кроме того, я должен сохранять состояние контекста перед обрезкой и восстанавливать его после рисования изображения, верно? Иначе мой путь проходит через обойму. - person Sebastian Celis; 14.04.2009
comment
Путь в текущем контуре нужен только в том случае, если вы собираетесь его заполнить или обвести. Рисование изображения не имеет ничего общего с текущим путем; на него влияет только обтравочный контур. И да, если вы хотите рисовать без обрезки после, вы должны сохранить до и восстановить после. - person Peter Hosey; 15.04.2009
comment
Но вам также понадобится путь в текущем пути, если вы собираетесь обрезать его (при вызове CGContextClip). Так что мне нужно дважды добавить путь к контексту, верно? Один раз прямо перед CGContextClip и один раз перед поглаживанием. Просто убедитесь, что я не упускаю никаких уловок. - person Sebastian Celis; 15.04.2009
comment
Ах, я пропустил, что вы гладите - я думал, вы просто рисуете изображение. Вы можете использовать CGPath только для построения пути один раз: постройте путь в объекте CGPath, затем добавьте CGPath к текущему пути, gsave, clip, отрисовку изображения, grestore и обводку. - person Peter Hosey; 15.04.2009

На прошлой неделе я пытался сделать что-то подобное.

С вашим вопросом, ответом и другими вопросами и ответами я создал пример с решением.

https://github.com/GabrielMassana/TransparentRoudRectButton

введите описание изображения здесь

person Gabriel.Massana    schedule 06.01.2015