2016-06-22 3 views
2

Я дуга, которую я нарисовал следующим образом:IOS: CoreGraphics - Отсечение дуги с CGContextClip и lineCap = .Round

func drawBackgroundMask(context: CGContextRef, 
         center: CGPoint, 
         radius: CGFloat, 
         lineWidth: CGFloat, 
         startAngle: CGFloat, 
         endAngle: CGFloat) { 
    let adjustedRadius: CGFloat = radius - (lineWidth/2) - 0 

    CGContextSetLineWidth(context, lineWidth) 
    CGContextSetLineCap(context, .Round) 

    CGContextAddArc(context, 
        center.x, 
        center.y, 
        adjustedRadius, 
        startAngle, 
        endAngle, 
        0) 

    //CGContextClosePath(context) 
    //CGContextClip(context) 
    CGContextStrokePath(context) 

} 

С учетом указанных выше линий закомментированными, я могу создать следующее:

black arc

Однако, если я пытаюсь использовать обнаженную форму в качестве маски раскомментировава-из двух строк коды выше, а затем закрашивания фона твердых, я получить другой результат:

func drawBackgroundMask(context: CGContextRef, 
         center: CGPoint, 
         radius: CGFloat, 
         lineWidth: CGFloat, 
         startAngle: CGFloat, 
         endAngle: CGFloat) { 
    let adjustedRadius: CGFloat = radius - (lineWidth/2) - 0 

    CGContextSetLineWidth(context, lineWidth) 
    CGContextSetLineCap(context, .Round) 

    CGContextAddArc(context, 
        center.x, 
        center.y, 
        adjustedRadius, 
        startAngle, 
        endAngle, 
        0) 

    CGContextClosePath(context) 
    CGContextClip(context) 
    CGContextStrokePath(context) 

    CGContextSetRGBFillColor(context, 100.0/255.0, 100.0/255.0, 100.0/255.0, 1.0); 
    CGContextFillRect(context, rect); 
} 

as mask

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

ответ

2

Во втором примере клип учитывает только путь дуги. Различные параметры удара, такие как ширина линии, колпачок и т. Д., Используются только тогда, когда вы на самом деле курсируете по пути, который вы не делаете.

Сначала вы установили путь в CGContext, затем закрепите его. После этого путь в контексте расходуется. Как the documentation говорит:

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

Так что, когда вы звоните CGContextStrokePath, это не имеет никакого эффекта, потому что в то время путь тока в CGContext пусто.

Похоже, вы хотите использовать CGContextReplacePathWithStrokedPath перед тем, как клипнуть. В документации даже упоминается этот конкретный прецедент:

Например, вы можете кликать по поглаженной версии пути, вызывая эту функцию, а затем вызов функции CGContextClip.

func drawBackgroundMask(context: CGContextRef, 
        center: CGPoint, 
        radius: CGFloat, 
        lineWidth: CGFloat, 
        startAngle: CGFloat, 
        endAngle: CGFloat) { 
    let adjustedRadius: CGFloat = radius - (lineWidth/2) - 0 

    CGContextSetLineWidth(context, lineWidth) 
    CGContextSetLineCap(context, .Round) 

    CGContextAddArc(context, 
        center.x, 
        center.y, 
        adjustedRadius, 
        startAngle, 
        endAngle, 
        0) 

    CGContextReplacePathWithStrokedPath(context) 
    CGContextClip(context) 

    CGContextSetRGBFillColor(context, 100.0/255.0, 100.0/255.0, 100.0/255.0, 1.0); 
    CGContextFillRect(context, rect); 
}