Я думаю, вы хотите это:
![rounded staircase](https://i.stack.imgur.com/8kquE.png)
Существуют основные графические функции для скругления углов, которые недоступны на UIBezierPath
. Это CGContextAddArcToPoint
и CGPathAddArcToPoint
. Я объясню, как они работают.
Сначала давайте рассмотрим, как вы рисуете две линии, встречающиеся в остром углу. Когда путь инициализируется впервые, его «текущая точка» находится в начале координат:
![current point at origin](https://i.stack.imgur.com/qcut2.png)
Вы используете CGPathMoveToPoint
, чтобы перейти к началу первой строки на (x0, y0)
:
![after move](https://i.stack.imgur.com/Qz8tW.png)
Затем вы используете CGPathAddLineToPoint
, чтобы нарисовать первую линию, заканчивающуюся в углу на (x1, y1)
:
![after first line](https://i.stack.imgur.com/OTXZs.png)
Наконец, вы снова используете CGPathAddLineToPoint
, чтобы нарисовать вторую линию для (x2, y2)
:
![after second line](https://i.stack.imgur.com/8GYvW.png)
Теперь давайте используем CGPathAddArcToPoint
, чтобы закруглить угол. Перемотайте сразу после того, как вы использовали CGPathMoveToPoint
для перехода к началу первой строки:
![after move](https://i.stack.imgur.com/Qz8tW.png)
CGPathAddArcToPoint
принимает две точки: точку на углу (которая не будет достигнута, поскольку она закруглит угол) и следующую точку в форме после угла. Таким образом, вы передаете его как (x1,y1)
(угол) и (x2,y2)
(конец следующей строки). Вы также передаете ему радиус угла:
![after first line and corner](https://i.stack.imgur.com/PvEMa.png)
Обратите внимание, что CGPathAddArcToPoint
рисует для вас первую линию, и рисует дугу, которая образует закругленный угол, и оставляет текущую точку в конце этой дуги. Таким образом, вы затем используете CGPathAddLineToPoint
, чтобы нарисовать вторую линию:
![after second line](https://i.stack.imgur.com/4kPlw.png)
Хорошо, это объясняет (я надеюсь), как работает CGPathAddArcToPoint
. CGContextAddArcToPoint
работает так же, но работает по пути контекста.
Чтобы применить это к форме лестницы, вы хотите использовать функцию CG*AddArcToPoint
, чтобы рисовать каждый угол. Поскольку у вас замкнутая форма и вам не нужны острые углы, вам вообще не нужно использовать CG*AddLineToPoint
. Вы можете использовать функцию дуги, чтобы нарисовать каждую линию, а также закругленные углы.
Одна вещь, о которой нужно быть осторожным, это то, где вы начинаете форму. Вы не можете начать с угла, потому что тогда вы получите прямую линию из угла. Вместо этого проще всего начать с середины одной из линий, далеко от любого угла.
Кроме того, поскольку вы делаете это в drawRect:
, вы можете просто использовать путь контекста вместо создания отдельного объекта UIBezierPath
или CGPath
. Вот код, который я использовал, чтобы нарисовать результат выше:
- (void)drawRect:(CGRect)rect {
CGPoint p[] = {
{100, 100},
{150, 100},
{150, 150},
{200, 150},
{200, 200},
{250, 200},
{250, 250},
{100, 250},
};
size_t count = (sizeof p) / (sizeof p[0]);
CGPoint pLast = p[count - 1];
CGContextRef gc = UIGraphicsGetCurrentContext();
// Start at the midpoint of one of the lines.
CGContextMoveToPoint(gc, 0.5 * (pLast.x + p[0].x), 0.5 * (pLast.y + p[0].y));
for (size_t i = 1; i < count; ++i) {
CGContextAddArcToPoint(gc, p[i-1].x, p[i-1].y, p[i].x, p[i].y, 10);
}
CGContextAddArcToPoint(gc, pLast.x, pLast.y, p[0].x, p[0].y, 10);
// Connect the last corner's arc to the starting point.
CGContextClosePath(gc);
[UIColor.greenColor setFill];
CGContextFillPath(gc);
}