Objective c iPhone X系列上的UIBezierPath圆弧和矩形问题,但早期手机上没有
我已经为UIView创建了Objective-C类别来绘制圆角。我正在尝试实现一个Pill按钮,除了在iPhoneX系列上,该功能都可以正常工作。因为圆弧位于UIView的末端,所以我想我必须将视图的其余部分绘制为矩形来填充。如果有更好的方法,我很想知道。下面是函数Objective c iPhone X系列上的UIBezierPath圆弧和矩形问题,但早期手机上没有,objective-c,uibezierpath,iphone-x,Objective C,Uibezierpath,Iphone X,我已经为UIView创建了Objective-C类别来绘制圆角。我正在尝试实现一个Pill按钮,除了在iPhoneX系列上,该功能都可以正常工作。因为圆弧位于UIView的末端,所以我想我必须将视图的其余部分绘制为矩形来填充。如果有更好的方法,我很想知道。下面是函数 - (void)setRounded:(BOOL)clockwise borderColor:(UIColor *)borderColor { CGRect rect = self.bounds; CGFloat
- (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];
}
我要做的就是把整个药丸形状画成一条路径,然后填充它。以下是一个UIView子类,它将自身绘制为一个药丸形状: 所以你看,这只是一个设置视图大小和比例的问题,不管你在什么设备上运行,药丸都会出现 以下是pill视图的代码:
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()
}
}
我不明白你的策略。这条方形小径是干什么用的?你为什么不把整个药丸的形状画成一条路径呢?谢谢,我想我不知道你能做到。我想我发现了真正的问题所在。iPhone X的分辨率更高,但宽度很奇怪,即375。因此,在创建中间标签时,宽度甚至创建了一个带有.5的宽度,但分辨率不正确。我通过计算屏幕宽度为偶数8加上或奇数x的标签来解决这个问题,现在它看起来是正确的。这也是为什么我更喜欢视图自身绘制的解决方案,而您所要做的就是像往常一样使用约束来调整视图的大小/位置。我给出的解决方案不会失败,因为它不依赖于关于分辨率、大小或任何其他方面的任何假设。