Я хочу обойти каждый уголок этого. Я использую UIBezierPath для рисования и установки
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
это не работает.
У меня есть удобный способ сделать это вместо последовательности addLineToPoint
и addArcWithCenter
В пользовательском представлении
- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(150, 100)];
[path addLineToPoint:CGPointMake(150, 150)];
[path addLineToPoint:CGPointMake(200, 150)];
[path addLineToPoint:CGPointMake(200, 200)];
[path addLineToPoint:CGPointMake(250, 200)];
[path addLineToPoint:CGPointMake(250, 250)];
[path addLineToPoint:CGPointMake(100, 250)];
[path closePath];
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetFillColorWithColor(context, UIColor.greenColor.CGColor);
CGContextAddPath(context, path.CGPath);
CGContextFillPath(context);
CGContextRestoreGState(context);
}
В Viewcontroller
- (void)viewDidLoad {
[super viewDidLoad];
testvvv *test = [[testvvv alloc] initWithFrame:self.view.bounds];
[self.view addSubview:test];
}
Вы можете добавить закругленный угол в траекторию Безье, используя метод ниже.
path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2) , clockwise: true)
Добавленный вами код kCGLineCapRound
работает нормально.
kCGLineCapRound
предназначен для пути, попробуйте добавить немного lineWidth
для пути.
Вы увидите разницу.
path.lineWidth = 50.0
При необходимости вы можете установить его strokeColor
таким же, как цвет заливки.
Очень хороший пост на uibezierpath Рисование UIBezierPath в коде, созданном UIView
@HensonFang, пожалуйста, ссылайтесь на этот пост. Это очень хороший пост на uibezierpath stackoverflow.com/questions/21311880/…
Я думаю, вы этого хотите:
Есть функции Core Graphics для скругления углов, которые недоступны в UIBezierPath
. Это CGContextAddArcToPoint
и CGPathAddArcToPoint
. Я объясню, как они работают.
Сначала давайте рассмотрим, как вы рисуете две линии, пересекающиеся в остром углу. Когда путь инициализируется впервые, его «текущая точка» находится в начале координат:
Вы используете CGPathMoveToPoint
для перехода к началу первой строки в (x0, y0)
:
Затем вы используете CGPathAddLineToPoint
, чтобы нарисовать первую линию, заканчивающуюся углом на (x1, y1)
:
Наконец, вы снова используете CGPathAddLineToPoint
, чтобы провести вторую линию к (x2, y2)
:
Теперь давайте воспользуемся CGPathAddArcToPoint
, чтобы вместо этого закруглить угол. Перемотайте назад сразу после того, как вы использовали CGPathMoveToPoint
для перехода к началу первой строки:
CGPathAddArcToPoint
принимает точки два: точка в углу (которая не будет достигнута, так как она будет закругляться) и следующая точка в форме после угла. Таким образом, вы передаете ему как (x1,y1)
(угол), так и (x2,y2)
(конец следующей строки). Вы также передаете ему радиус угла:
Обратите внимание, что CGPathAddArcToPoint
рисует для вас первую линию и дугу, образующую закругленный угол, и оставляет текущую точку в конце этой дуги. Затем вы используете CGPathAddLineToPoint
, чтобы нарисовать вторую линию:
Хорошо, это объясняет (я надеюсь), как работает 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);
}
{22, 104.33333333333333}, {22, 135.33333333333334}, {23.333333333333332, 136.33333333333334}, {23.333333333333332, 167.33333333333334}, {351, 167.33333333333334}, {351, 136.33333333333334}, {352, 135.33333333333334}, {352, 104.33333333333333}
, если я перейду на этот массив прямоугольников, форма пойдет не так
Выложите, пожалуйста, новый отдельный вопрос с изображением проблемы.
Да, он может это сделать, но может быть слишком много линий и дуг для расчета, есть ли удобный способ сделать это?