Проблема дуги и прямоугольника UIBezierPath в семействе iPhone X, но не в более ранних телефонах
Я создал категорию Objective-C для UIView, чтобы рисовать закругленные углы. Я пытаюсь реализовать кнопку Pill, и эта функция работает, кроме iPhone X. Поскольку Дуга находится в конце UIView, я думаю, что мне нужно нарисовать остальную часть представления в виде прямоугольника для заполнения. Если есть лучший способ сделать это, я бы хотел знать. Вот функция.
- (void)setRounded:(BOOL)clockwise borderColor:(UIColor *)borderColor {
CGRect rect = self.bounds;
CGFloat offset = CGRectGetMidY(rect);
NSAssert(rect.size.width-rect.origin.x >= offset, @"width too small %f < %f", rect.size.width, offset);
UIBezierPath *maskPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(clockwise?rect.size.width-rect.origin.x-offset:rect.origin.x+offset, offset) radius:offset startAngle:GLKMathDegreesToRadians(270) endAngle:GLKMathDegreesToRadians(90) clockwise:clockwise];
DLog(@"(clockwise: %@) maskPath: %@", clockwise?@"true":@"false", NSStringFromCGRect([maskPath bounds]));
[maskPath setUsesEvenOddFillRule:NO];
UIBezierPath *squarePath = [UIBezierPath bezierPath];
if (clockwise) {
[squarePath moveToPoint:CGPointMake(rect.origin.x, rect.origin.y)];
[squarePath addLineToPoint:CGPointMake(rect.size.width-rect.origin.x-offset, rect.origin.y)];
[squarePath addLineToPoint:CGPointMake(rect.size.width-rect.origin.x-offset, rect.origin.y+rect.size.height)];
[squarePath addLineToPoint:CGPointMake(rect.origin.x, rect.origin.y+rect.size.height)];
[squarePath addLineToPoint:CGPointMake(rect.origin.x, rect.origin.y)];
} else {
[squarePath moveToPoint:CGPointMake(rect.origin.x+offset, rect.origin.y)];
[squarePath addLineToPoint:CGPointMake(rect.size.width-rect.origin.x, rect.origin.y)];
[squarePath addLineToPoint:CGPointMake(rect.size.width-rect.origin.x, round(rect.origin.y+rect.size.height))];
[squarePath addLineToPoint:CGPointMake(rect.origin.x+offset, round(rect.origin.y+rect.size.height))];
//[squarePath addLineToPoint:CGPointMake(rect.origin.x+offset, rect.origin.y)];
[squarePath closePath];
}
DLog(@"squarePath: %@", NSStringFromCGRect([squarePath bounds]));
[maskPath appendPath:squarePath];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = rect;
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
CAShapeLayer *shape = [CAShapeLayer layer];
shape.frame = self.frame;
shape.path = maskPath.CGPath;
shape.lineWidth = 1.0;
shape.strokeColor = borderColor.CGColor;
shape.fillColor = borderColor.CGColor;
[self.layer addSublayer:shape];
}
1 ответ
То, что я хотел бы сделать, это просто нарисовать всю форму таблетки в виде одного пути и заполнить его. Вот подкласс UIView, который рисует себя в виде таблетки:
Таким образом, вы видите, что это просто вопрос установки размера и пропорций этого вида так, как вы хотите, и таблетка просто появится, независимо от того, на каком устройстве вы работаете.
Вот код для просмотра таблеток:
class PillView : UIView {
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
self.isOpaque = false
}
override func draw(_ rect: CGRect) {
let ins : CGFloat = 2
let r = self.bounds.insetBy(dx: ins, dy: ins)
let radius : CGFloat = r.size.height / 2
let d90 = CGFloat.pi/2
let path = CGMutablePath()
path.move(to:CGPoint(x:r.maxX - radius, y:ins))
path.addArc(center:CGPoint(x:radius+ins, y:radius+ins), radius: radius,
startAngle: -d90, endAngle: d90, clockwise: true)
path.addArc(center:CGPoint(x:r.maxX - radius, y:radius+ins), radius: radius,
startAngle: d90, endAngle: -d90, clockwise: true)
path.closeSubpath()
let bez = UIBezierPath()
bez.cgPath = path
UIColor.green.setFill()
bez.fill()
}
}