这是我的代码:
CGRect rect = cell.profilePic.frame;CAShapeLayer *hexagonMask = [CAShapeLayer layer];CAShapeLayer *hexagonborder = [CAShapeLayer layer];hexagonborder.frame = cell.profilePic.layer.bounds;UIBezIErPath *hexagonPath = [UIBezIErPath bezIErPath];CGfloat sIDeWIDth = 2 * ( 0.5 * rect.size.wIDth / 2 );CGfloat lcolumn = ( rect.size.wIDth - sIDeWIDth ) / 2;CGfloat rcolumn = rect.size.wIDth - lcolumn;CGfloat height = 0.866025 * rect.size.height;CGfloat y = (rect.size.height - height) / 2;CGfloat by = rect.size.height - y;CGfloat mIDy = rect.size.height / 2;CGfloat rightmost = rect.size.wIDth;[hexagonPath movetoPoint:CGPointMake(lcolumn,y)];[hexagonPath addlinetoPoint:CGPointMake(rcolumn,y)];[hexagonPath addlinetoPoint:CGPointMake(rightmost,mIDy)];[hexagonPath addlinetoPoint:CGPointMake(rcolumn,by)];[hexagonPath addlinetoPoint:CGPointMake(lcolumn,by)];[hexagonPath addlinetoPoint:CGPointMake(0,mIDy)];[hexagonPath addlinetoPoint:CGPointMake(lcolumn,y)];hexagonMask.path = hexagonPath.CGPath;hexagonborder.path = hexagonPath.CGPath;hexagonborder.fillcolor = [UIcolor clearcolor].CGcolor;hexagonborder.strokecolor = [UIcolor blackcolor].CGcolor;hexagonborder.linewidth = 5;cell.profilePic.layer.mask = hexagonMask;cell.profilePic.layer.cornerRadius = 10;cell.profilePic.layer.masksToBounds = YES;[cell.profilePic.layer addSublayer:hexagonborder];
有任何想法吗?
谢谢
解决方法 您可以定义一个带圆角的六边形路径(手动定义该路径),然后将其应用为蒙版和边框子图层:CGfloat linewidth = 5.0;UIBezIErPath *path = [UIBezIErPath polygonInRect:self.imageVIEw.bounds sIDes:6 linewidth:linewidth cornerRadius:30];// mask for the image vIEwCAShapeLayer *mask = [CAShapeLayer layer];mask.path = path.CGPath;mask.linewidth = linewidth;mask.strokecolor = [UIcolor clearcolor].CGcolor;mask.fillcolor = [UIcolor whitecolor].CGcolor;self.imageVIEw.layer.mask = mask;// if you also want a border,add that as a separate layerCAShapeLayer *border = [CAShapeLayer layer];border.path = path.CGPath;border.linewidth = linewidth;border.strokecolor = [UIcolor blackcolor].CGcolor;border.fillcolor = [UIcolor clearcolor].CGcolor;[self.imageVIEw.layer addSublayer:border];
具有圆角的正多边形的路径可能在类似的类别中实现:
@interface UIBezIErPath (polygon)/** Create UIBezIErPath for regular polygon with rounded corners * * @param rect The CGRect of the square in which the path should be created. * @param sIDes How many sIDes to the polygon (e.g. 6=hexagon; 8=octagon,etc.). * @param linewidth The wIDth of the stroke around the polygon. The polygon will be inset such that the stroke stays within the above square. * @param cornerRadius The radius to be applIEd when rounding the corners. * * @return UIBezIErPath of the resulting rounded polygon path. */+ (instancetype)polygonInRect:(CGRect)rect sIDes:(NSInteger)sIDes linewidth:(CGfloat)linewidth cornerRadius:(CGfloat)cornerRadius;@end
和
@implementation UIBezIErPath (polygon)+ (instancetype)polygonInRect:(CGRect)rect sIDes:(NSInteger)sIDes linewidth:(CGfloat)linewidth cornerRadius:(CGfloat)cornerRadius { UIBezIErPath *path = [UIBezIErPath bezIErPath]; CGfloat theta = 2.0 * M_PI / sIDes; // how much to turn at every corner CGfloat offset = cornerRadius * tanf(theta / 2.0); // offset from which to start rounding corners CGfloat squareWIDth = MIN(rect.size.wIDth,rect.size.height); // wIDth of the square // calculate the length of the sIDes of the polygon CGfloat length = squareWIDth - linewidth; if (sIDes % 4 != 0) { // if not dealing with polygon which will be square with all sIDes ... length = length * cosf(theta / 2.0) + offset/2.0; // ... offset it insIDe a circle insIDe the square } CGfloat sIDeLength = length * tanf(theta / 2.0); // start drawing at `point` in lower right corner CGPoint point = CGPointMake(rect.origin.x + rect.size.wIDth / 2.0 + sIDeLength / 2.0 - offset,rect.origin.y + rect.size.height / 2.0 + length / 2.0); CGfloat angle = M_PI; [path movetoPoint:point]; // draw the sIDes and rounded corners of the polygon for (NSInteger sIDe = 0; sIDe < sIDes; sIDe++) { point = CGPointMake(point.x + (sIDeLength - offset * 2.0) * cosf(angle),point.y + (sIDeLength - offset * 2.0) * sinf(angle)); [path addlinetoPoint:point]; CGPoint center = CGPointMake(point.x + cornerRadius * cosf(angle + M_PI_2),point.y + cornerRadius * sinf(angle + M_PI_2)); [path addArcWithCenter:center radius:cornerRadius startAngle:angle - M_PI_2 endAngle:angle + theta - M_PI_2 clockwise:YES]; point = path.currentPoint; // we don't have to calculate where the arc ended ... UIBezIErPath dID that for us angle += theta; } [path closePath]; path.linewidth = linewidth; // in case we're going to use CoreGraphics to stroke path,rather than CAShapeLayer path.lineJoinStyle = kCGlineJoinRound; return path;}
产生这样的结果:
或者在Swift 3中你可以这样做:
let linewidth: CGfloat = 5let path = UIBezIErPath(polygonIn: imageVIEw.bounds,sIDes: 6,linewidth: linewidth,cornerRadius: 30)let mask = CAShapeLayer()mask.path = path.cgPathmask.linewidth = linewidthmask.strokecolor = UIcolor.clear.cgcolormask.fillcolor = UIcolor.white.cgcolorimageVIEw.layer.mask = masklet border = CAShapeLayer()border.path = path.cgPathborder.linewidth = linewidthborder.strokecolor = UIcolor.black.cgcolorborder.fillcolor = UIcolor.clear.cgcolorimageVIEw.layer.addSublayer(border)
同
extension UIBezIErPath { /// Create UIBezIErPath for regular polygon with rounded corners /// /// - parameter rect: The CGRect of the square in which the path should be created. /// - parameter sIDes: How many sIDes to the polygon (e.g. 6=hexagon; 8=octagon,etc.). /// - parameter linewidth: The wIDth of the stroke around the polygon. The polygon will be inset such that the stroke stays within the above square. Default value 1. /// - parameter cornerRadius: The radius to be applIEd when rounding the corners. Default value 0. convenIEnce init(polygonIn rect: CGRect,sIDes: Int,linewidth: CGfloat = 1,cornerRadius: CGfloat = 0) { self.init() let theta = 2 * CGfloat.pi / CGfloat(sIDes) // how much to turn at every corner let offset = cornerRadius * tan(theta / 2) // offset from which to start rounding corners let squareWIDth = min(rect.size.wIDth,rect.size.height) // wIDth of the square // calculate the length of the sIDes of the polygon var length = squareWIDth - linewidth if sIDes % 4 != 0 { // if not dealing with polygon which will be square with all sIDes ... length = length * cos(theta / 2) + offset / 2 // ... offset it insIDe a circle insIDe the square } let sIDeLength = length * tan(theta / 2) // if you'd like to start rotated 90 degrees,use these lines instead of the following two: // // var point = CGPoint(x: rect.mIDX - length / 2,y: rect.mIDY + sIDeLength / 2 - offset) // var angle = -CGfloat.pi / 2.0 // if you'd like to start rotated 180 degrees,use these lines instead of the following two: // // var point = CGPoint(x: rect.mIDX - sIDeLength / 2 + offset,y: rect.mIDY - length / 2) // var angle = CGfloat(0) var point = CGPoint(x: rect.mIDX + sIDeLength / 2 - offset,y: rect.mIDY + length / 2) var angle = CGfloat.pi move(to: point) // draw the sIDes and rounded corners of the polygon for _ in 0 ..< sIDes { point = CGPoint(x: point.x + (sIDeLength - offset * 2) * cos(angle),y: point.y + (sIDeLength - offset * 2) * sin(angle)) addline(to: point) let center = CGPoint(x: point.x + cornerRadius * cos(angle + .pi / 2),y: point.y + cornerRadius * sin(angle + .pi / 2)) addArc(withCenter: center,radius: cornerRadius,startAngle: angle - .pi / 2,endAngle: angle + theta - .pi / 2,clockwise: true) point = currentPoint angle += theta } close() self.linewidth = linewidth // in case we're going to use CoreGraphics to stroke path,rather than CAShapeLayer lineJoinStyle = .round }}
对于Swift 2的演绎,请参阅previous revision of this answer.
总结以上是内存溢出为你收集整理的ios – 如何用Hexagon面具圆角UIImage的角落全部内容,希望文章能够帮你解决ios – 如何用Hexagon面具圆角UIImage的角落所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)