我希望将我的UIView
改为具有类似值的值
top-left-radius:20;
bottom-right-radius:5;
bottom-left-radius:5;
和top-right-radius:10;
//For rounder `UIRectCornerBottomLeft & UIRectCornerBottomRight` I use
UIBezierPath *maskPath0 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(5.0, 5.0)];
CAShapeLayer *maskLayer0 = [[CAShapeLayer alloc] init];
maskLayer0.frame = self.bounds;
maskLayer0.path = maskPath0.CGPath;
self.messageView.layer.mask = maskLayer0;
//For rounder `TopRight` I use
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;
self.messageView.layer.mask = maskLayer;
//For rounder `TopLeft` I use
UIBezierPath *maskPath2 = [UIBezierPath bezierPathWithRoundedRect:self.messageView.bounds byRoundingCorners:(UIRectCornerTopLeft) cornerRadii:CGSizeMake(20.0, 20.0)];
CAShapeLayer *maskLayer2 = [[CAShapeLayer alloc] init];
maskLayer2.frame = self.bounds;
maskLayer2.path = maskPath2.CGPath;
self.messageView.layer.mask = maskLayer2;
但我得到的结果是角半径TopLeft
的视图值为20。
我怎样才能实现这个圆?任何帮助将不胜感激。
答案 0 :(得分:7)
UIBezierPath
没有这样的方法。但您可以使用大量addLineToPoint
和addArcWithCenter
方法来执行此操作:
let minx = CGRectGetMinX(rect)
let miny = CGRectGetMinY(rect)
let maxx = CGRectGetMaxX(rect)
let maxy = CGRectGetMaxY(rect)
let path = UIBezierPath()
path.moveToPoint(CGPointMake(minx + topLeftRadius, miny))
path.addLineToPoint(CGPointMake(maxx - topRightRadius, miny))
path.addArcWithCenter(CGPointMake(maxx - topRightRadius, miny + topRightRadius), radius: topRightRadius, startAngle:3 * M_PI_2, endAngle: 0, clockwise: true)
path.addLineToPoint(CGPointMake(maxx, maxy - bottomRightRadius))
path.addArcWithCenter(CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius), radius: bottomRightRadius, startAngle: 0, endAngle: M_PI_2, clockwise: true)
path.addLineToPoint(CGPointMake(minx + bottomLeftRadius, maxy))
path.addArcWithCenter(CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius), radius: bottomLeftRadius, startAngle: M_PI_2, endAngle: M_PI, clockwise: true)
path.addLineToPoint(CGPointMake(minx, miny + topLeftRadius))
path.addArcWithCenter(CGPointMake(minx + topLeftRadius, miny + topLeftRadius), radius: topLeftRadius, startAngle: M_PI, endAngle: 3 * M_PI_2, clockwise: true)
path.closePath()
对于Obj-C:
CGFloat topLeftRadius = 20;
CGFloat topRightRadius = 10;
CGFloat bottomRightRadius = 5;
CGFloat bottomLeftRadius = 5;
CGFloat minx = CGRectGetMinX(self.messageView.bounds);
CGFloat miny = CGRectGetMinY(self.messageView.bounds);
CGFloat maxx = CGRectGetMaxX(self.messageView.bounds);
CGFloat maxy = CGRectGetMaxY(self.messageView.bounds);
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(minx + topLeftRadius, miny)];
[path addLineToPoint:CGPointMake(maxx - topRightRadius, miny)];
[path addArcWithCenter:CGPointMake(maxx - topRightRadius, miny + topRightRadius) radius: topRightRadius startAngle: 3 * M_PI_2 endAngle: 0 clockwise: YES];
[path addLineToPoint:CGPointMake(maxx, maxy - bottomRightRadius)];
[path addArcWithCenter:CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius) radius: bottomRightRadius startAngle: 0 endAngle: M_PI_2 clockwise: YES];
[path addLineToPoint:CGPointMake(minx + bottomLeftRadius, maxy)];
[path addArcWithCenter:CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius) radius: bottomLeftRadius startAngle: M_PI_2 endAngle:M_PI clockwise: YES];
[path addLineToPoint:CGPointMake(minx, miny + topLeftRadius)];
[path addArcWithCenter:CGPointMake(minx + topLeftRadius, miny + topLeftRadius) radius: topLeftRadius startAngle: M_PI endAngle:3 * M_PI_2 clockwise: YES];
[path closePath];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.path = path.CGPath;
self.messageView.layer.mask = maskLayer;
答案 1 :(得分:7)
这是一个UIBezierPath类别,可以按照某些现有初始值设定项的模式执行您想要的操作:
extension UIBezierPath {
public convenience init(roundedRect rect: CGRect, topLeftRadius: CGFloat?, topRightRadius: CGFloat?, bottomLeftRadius: CGFloat?, bottomRightRadius: CGFloat?) {
self.init()
assert(((bottomLeftRadius ?? 0) + (bottomRightRadius ?? 0)) <= rect.size.width)
assert(((topLeftRadius ?? 0) + (topRightRadius ?? 0)) <= rect.size.width)
assert(((topLeftRadius ?? 0) + (bottomLeftRadius ?? 0)) <= rect.size.height)
assert(((topRightRadius ?? 0) + (bottomRightRadius ?? 0)) <= rect.size.height)
// corner centers
let tl = CGPoint(x: rect.minX + (topLeftRadius ?? 0), y: rect.minY + (topLeftRadius ?? 0))
let tr = CGPoint(x: rect.maxX - (topRightRadius ?? 0), y: rect.minY + (topRightRadius ?? 0))
let bl = CGPoint(x: rect.minX + (bottomLeftRadius ?? 0), y: rect.maxY - (bottomLeftRadius ?? 0))
let br = CGPoint(x: rect.maxX - (bottomRightRadius ?? 0), y: rect.maxY - (bottomRightRadius ?? 0))
//let topMidpoint = CGPoint(rect.midX, rect.minY)
let topMidpoint = CGPoint(x: rect.midX, y: rect.minY)
makeClockwiseShape: do {
self.move(to: topMidpoint)
if let topRightRadius = topRightRadius {
self.addLine(to: CGPoint(x: rect.maxX - topRightRadius, y: rect.minY))
self.addArc(withCenter: tr, radius: topRightRadius, startAngle: -CGFloat.pi/2, endAngle: 0, clockwise: true)
}
else {
self.addLine(to: tr)
}
if let bottomRightRadius = bottomRightRadius {
self.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - bottomRightRadius))
self.addArc(withCenter: br, radius: bottomRightRadius, startAngle: 0, endAngle: CGFloat.pi/2, clockwise: true)
}
else {
self.addLine(to: br)
}
if let bottomLeftRadius = bottomLeftRadius {
self.addLine(to: CGPoint(x: rect.minX + bottomLeftRadius, y: rect.maxY))
self.addArc(withCenter: bl, radius: bottomLeftRadius, startAngle: CGFloat.pi/2, endAngle: CGFloat.pi, clockwise: true)
}
else {
self.addLine(to: bl)
}
if let topLeftRadius = topLeftRadius {
self.addLine(to: CGPoint(x: rect.minX, y: rect.minY + topLeftRadius))
self.addArc(withCenter: tl, radius: topLeftRadius, startAngle: CGFloat.pi, endAngle: -CGFloat.pi/2, clockwise: true)
}
else {
self.addLine(to: tl)
}
self.close()
}
}
}
答案 2 :(得分:0)
@ Mikhail-Grebionkin的答案的Swift 5 UIView扩展版本:
extension UIView {
func makeCustomRound(topLeft: CGFloat = 0, topRight: CGFloat = 0, bottomLeft: CGFloat = 0, bottomRight: CGFloat = 0) {
let minX = bounds.minX
let minY = bounds.minY
let maxX = bounds.maxX
let maxY = bounds.maxY
let path = UIBezierPath()
path.move(to: CGPoint(x: minX + topLeft, y: minY))
path.addLine(to: CGPoint(x: maxX - topRight, y: minY))
path.addArc(withCenter: CGPoint(x: maxX - topRight, y: minY + topRight), radius: topRight, startAngle:CGFloat(3 * Double.pi / 2), endAngle: 0, clockwise: true)
path.addLine(to: CGPoint(x: maxX, y: maxY - bottomRight))
path.addArc(withCenter: CGPoint(x: maxX - bottomRight, y: maxY - bottomRight), radius: bottomRight, startAngle: 0, endAngle: CGFloat(Double.pi / 2), clockwise: true)
path.addLine(to: CGPoint(x: minX + bottomLeft, y: maxY))
path.addArc(withCenter: CGPoint(x: minX + bottomLeft, y: maxY - bottomLeft), radius: bottomLeft, startAngle: CGFloat(Double.pi / 2), endAngle: CGFloat(Double.pi), clockwise: true)
path.addLine(to: CGPoint(x: minX, y: minY + topLeft))
path.addArc(withCenter: CGPoint(x: minX + topLeft, y: minY + topLeft), radius: topLeft, startAngle: CGFloat(Double.pi), endAngle: CGFloat(3 * Double.pi / 2), clockwise: true)
path.close()
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}