2013-12-03 1 views
3

Я рисую дугу, создавая CAShapeLayer и придав ему путь Безье следующим образом:Могу ли я добавить пользовательскую строку в UIBezierPath?

self.arcLayer = [CAShapeLayer layer]; 
UIBezierPath *remainingLayerPath = [UIBezierPath bezierPathWithArcCenter:self.center 
                    radius:100 
                   startAngle:DEGREES_TO_RADIANS(135) 
                   endAngle:DEGREES_TO_RADIANS(45) 
                   clockwise:YES]; 
self.arcLayer.path = remainingLayerPath.CGPath; 
self.arcLayer.position = CGPointMake(0,0); 

self.arcLayer.fillColor = [UIColor clearColor].CGColor; 
self.arcLayer.strokeColor = [UIColor blueColor].CGColor; 
self.arcLayer.lineWidth = 15; 

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

Я могу думать только о двух реальных вариантах, и я не в восторге ни от одного из них. Я могу придумать совершенно обычную траекторию Безье, прослеживающую внешнюю сторону дуги, в комплекте с моими закругленными краями. Я обеспокоен тем, что смогу анимировать дугу таким же образом (сейчас я просто оживляю ход с 0 до 1). Другой вариант заключается в том, чтобы оставить квадраты концевых шапок и замаскировать углы, но я понимаю, что маскировка относительно дорога, и я планирую сделать довольно интенсивную анимацию с этим представлением.

Любые предложения были бы полезными. Заранее спасибо.

+1

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

+0

@yurish Итак, как бы вы достигли желаемых результатов? – Mike

+0

Извините, не очень помогите здесь. Я бы попробовал первый подход, но не уверен, что вы можете успешно анимировать путь. – yurish

ответ

1

Я решил решить это, создав два полностью отдельных слоя: один для левой торцевой крышки и один для правой торцевой крышки. Вот правильный пример торцевой крышки:

self.rightEndCapLayer = [CAShapeLayer layer]; 
CGRect rightCapRect = CGRectMake(remainingLayerPath.currentPoint.x, remainingLayerPath.currentPoint.y, 0, 0); 
rightCapRect = CGRectInset(rightCapRect, self.arcWidth/-2, -1 * endCapRadius); 
self.rightEndCapLayer.frame = rightCapRect; 
self.rightEndCapLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.rightEndCapLayer.bounds 
                byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight 
                 cornerRadii:CGSizeMake(endCapRadius, endCapRadius)].CGPath; 
self.rightEndCapLayer.fillColor = self.remainingColor.CGColor; 

// Rotate the end cap 
self.rightEndCapLayer.anchorPoint = CGPointMake(.5, 0); 
self.rightEndCapLayer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(45), 0.0, 0.0, 1.0); 

[self.layer addSublayer:self.rightEndCapLayer]; 

Используя текущую точку Безье Path спасает от делать много математики, чтобы вычислить, где должна появиться конечная точка. Перемещение точки привязки также позволяет слоям не перекрываться, что важно, если ваша дуга абсолютно прозрачна.

Это все еще не совсем идеально, так как анимация должна быть скована несколькими слоями. Это лучше, чем альтернативы, которые я мог бы придумать.

+0

Что такое значение endcapRadius здесь –

+0

Я не думаю, что это в конечном итоге имеет значение, потому что вы делаете только заполнение, а не рисование линии. Но я ожидаю, что если это важно, это плоская крышка. – Mike