ios – 如何用Hexagon面具圆角UIImage的角落

前端之家收集整理的这篇文章主要介绍了ios – 如何用Hexagon面具圆角UIImage的角落前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试为我成功的UI Image添加一个六边形面具.但是我无法绕六边形面具的两侧.我想加上cell.profilePic.layer.cornerRadius = 10;会做的伎俩,但它没有.

这是我的代码

  1. CGRect rect = cell.profilePic.frame;
  2.  
  3. CAShapeLayer *hexagonMask = [CAShapeLayer layer];
  4. CAShapeLayer *hexagonBorder = [CAShapeLayer layer];
  5. hexagonBorder.frame = cell.profilePic.layer.bounds;
  6. UIBezierPath *hexagonPath = [UIBezierPath bezierPath];
  7. CGFloat sideWidth = 2 * ( 0.5 * rect.size.width / 2 );
  8. CGFloat lcolumn = ( rect.size.width - sideWidth ) / 2;
  9. CGFloat rcolumn = rect.size.width - lcolumn;
  10. CGFloat height = 0.866025 * rect.size.height;
  11. CGFloat y = (rect.size.height - height) / 2;
  12. CGFloat by = rect.size.height - y;
  13. CGFloat midy = rect.size.height / 2;
  14. CGFloat rightmost = rect.size.width;
  15. [hexagonPath moveToPoint:CGPointMake(lcolumn,y)];
  16. [hexagonPath addLineToPoint:CGPointMake(rcolumn,y)];
  17. [hexagonPath addLineToPoint:CGPointMake(rightmost,midy)];
  18. [hexagonPath addLineToPoint:CGPointMake(rcolumn,by)];
  19. [hexagonPath addLineToPoint:CGPointMake(lcolumn,by)];
  20. [hexagonPath addLineToPoint:CGPointMake(0,midy)];
  21. [hexagonPath addLineToPoint:CGPointMake(lcolumn,y)];
  22.  
  23. hexagonMask.path = hexagonPath.CGPath;
  24. hexagonBorder.path = hexagonPath.CGPath;
  25. hexagonBorder.fillColor = [UIColor clearColor].CGColor;
  26. hexagonBorder.strokeColor = [UIColor blackColor].CGColor;
  27. hexagonBorder.lineWidth = 5;
  28. cell.profilePic.layer.mask = hexagonMask;
  29. cell.profilePic.layer.cornerRadius = 10;
  30. cell.profilePic.layer.masksToBounds = YES;
  31. [cell.profilePic.layer addSublayer:hexagonBorder];

有任何想法吗?

谢谢

解决方法

您可以定义一个带圆角的六边形路径(手动定义该路径),然后将其应用为蒙版和边框子图层:
  1. CGFloat lineWidth = 5.0;
  2. UIBezierPath *path = [UIBezierPath polygonInRect:self.imageView.bounds
  3. sides:6
  4. lineWidth:lineWidth
  5. cornerRadius:30];
  6.  
  7. // mask for the image view
  8.  
  9. CAShapeLayer *mask = [CAShapeLayer layer];
  10. mask.path = path.CGPath;
  11. mask.lineWidth = lineWidth;
  12. mask.strokeColor = [UIColor clearColor].CGColor;
  13. mask.fillColor = [UIColor whiteColor].CGColor;
  14. self.imageView.layer.mask = mask;
  15.  
  16. // if you also want a border,add that as a separate layer
  17.  
  18. CAShapeLayer *border = [CAShapeLayer layer];
  19. border.path = path.CGPath;
  20. border.lineWidth = lineWidth;
  21. border.strokeColor = [UIColor blackColor].CGColor;
  22. border.fillColor = [UIColor clearColor].CGColor;
  23. [self.imageView.layer addSublayer:border];

具有圆角的正多边形的路径可能在类似的类别中实现:

  1. @interface UIBezierPath (Polygon)
  2.  
  3. /** Create UIBezierPath for regular polygon with rounded corners
  4. *
  5. * @param rect The CGRect of the square in which the path should be created.
  6. * @param sides How many sides to the polygon (e.g. 6=hexagon; 8=octagon,etc.).
  7. * @param lineWidth The width of the stroke around the polygon. The polygon will be inset such that the stroke stays within the above square.
  8. * @param cornerRadius The radius to be applied when rounding the corners.
  9. *
  10. * @return UIBezierPath of the resulting rounded polygon path.
  11. */
  12.  
  13. + (instancetype)polygonInRect:(CGRect)rect sides:(NSInteger)sides lineWidth:(CGFloat)lineWidth cornerRadius:(CGFloat)cornerRadius;
  14.  
  15. @end

  1. @implementation UIBezierPath (Polygon)
  2.  
  3. + (instancetype)polygonInRect:(CGRect)rect sides:(NSInteger)sides lineWidth:(CGFloat)lineWidth cornerRadius:(CGFloat)cornerRadius {
  4. UIBezierPath *path = [UIBezierPath bezierPath];
  5.  
  6. CGFloat theta = 2.0 * M_PI / sides; // how much to turn at every corner
  7. CGFloat offset = cornerRadius * tanf(theta / 2.0); // offset from which to start rounding corners
  8. CGFloat squareWidth = MIN(rect.size.width,rect.size.height); // width of the square
  9.  
  10. // calculate the length of the sides of the polygon
  11.  
  12. CGFloat length = squareWidth - lineWidth;
  13. if (sides % 4 != 0) { // if not dealing with polygon which will be square with all sides ...
  14. length = length * cosf(theta / 2.0) + offset/2.0; // ... offset it inside a circle inside the square
  15. }
  16. CGFloat sideLength = length * tanf(theta / 2.0);
  17.  
  18. // start drawing at `point` in lower right corner
  19.  
  20. 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);
  21. CGFloat angle = M_PI;
  22. [path moveToPoint:point];
  23.  
  24. // draw the sides and rounded corners of the polygon
  25.  
  26. for (NSInteger side = 0; side < sides; side++) {
  27. point = CGPointMake(point.x + (sideLength - offset * 2.0) * cosf(angle),point.y + (sideLength - offset * 2.0) * sinf(angle));
  28. [path addLineToPoint:point];
  29.  
  30. CGPoint center = CGPointMake(point.x + cornerRadius * cosf(angle + M_PI_2),point.y + cornerRadius * sinf(angle + M_PI_2));
  31. [path addArcWithCenter:center radius:cornerRadius startAngle:angle - M_PI_2 endAngle:angle + theta - M_PI_2 clockwise:YES];
  32.  
  33. point = path.currentPoint; // we don't have to calculate where the arc ended ... UIBezierPath did that for us
  34. angle += theta;
  35. }
  36.  
  37. [path closePath];
  38.  
  39. path.lineWidth = lineWidth; // in case we're going to use CoreGraphics to stroke path,rather than CAShapeLayer
  40. path.lineJoinStyle = kCGLineJoinRound;
  41.  
  42. return path;
  43. }

产生这样的结果:

或者在Swift 3中你可以这样做:

  1. let lineWidth: CGFloat = 5
  2. let path = UIBezierPath(polygonIn: imageView.bounds,sides: 6,lineWidth: lineWidth,cornerRadius: 30)
  3.  
  4. let mask = CAShapeLayer()
  5. mask.path = path.cgPath
  6. mask.lineWidth = lineWidth
  7. mask.strokeColor = UIColor.clear.cgColor
  8. mask.fillColor = UIColor.white.cgColor
  9. imageView.layer.mask = mask
  10.  
  11. let border = CAShapeLayer()
  12. border.path = path.cgPath
  13. border.lineWidth = lineWidth
  14. border.strokeColor = UIColor.black.cgColor
  15. border.fillColor = UIColor.clear.cgColor
  16. imageView.layer.addSublayer(border)

  1. extension UIBezierPath {
  2.  
  3. /// Create UIBezierPath for regular polygon with rounded corners
  4. ///
  5. /// - parameter rect: The CGRect of the square in which the path should be created.
  6. /// - parameter sides: How many sides to the polygon (e.g. 6=hexagon; 8=octagon,etc.).
  7. /// - 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.
  8. /// - parameter cornerRadius: The radius to be applied when rounding the corners. Default value 0.
  9.  
  10. convenience init(polygonIn rect: CGRect,sides: Int,lineWidth: CGFloat = 1,cornerRadius: CGFloat = 0) {
  11. self.init()
  12.  
  13. let theta = 2 * CGFloat.pi / CGFloat(sides) // how much to turn at every corner
  14. let offset = cornerRadius * tan(theta / 2) // offset from which to start rounding corners
  15. let squareWidth = min(rect.size.width,rect.size.height) // width of the square
  16.  
  17. // calculate the length of the sides of the polygon
  18.  
  19. var length = squareWidth - lineWidth
  20. if sides % 4 != 0 { // if not dealing with polygon which will be square with all sides ...
  21. length = length * cos(theta / 2) + offset / 2 // ... offset it inside a circle inside the square
  22. }
  23. let sideLength = length * tan(theta / 2)
  24.  
  25. // if you'd like to start rotated 90 degrees,use these lines instead of the following two:
  26. //
  27. // var point = CGPoint(x: rect.midX - length / 2,y: rect.midY + sideLength / 2 - offset)
  28. // var angle = -CGFloat.pi / 2.0
  29.  
  30. // if you'd like to start rotated 180 degrees,use these lines instead of the following two:
  31. //
  32. // var point = CGPoint(x: rect.midX - sideLength / 2 + offset,y: rect.midY - length / 2)
  33. // var angle = CGFloat(0)
  34.  
  35. var point = CGPoint(x: rect.midX + sideLength / 2 - offset,y: rect.midY + length / 2)
  36. var angle = CGFloat.pi
  37.  
  38. move(to: point)
  39.  
  40. // draw the sides and rounded corners of the polygon
  41.  
  42. for _ in 0 ..< sides {
  43. point = CGPoint(x: point.x + (sideLength - offset * 2) * cos(angle),y: point.y + (sideLength - offset * 2) * sin(angle))
  44. addLine(to: point)
  45.  
  46. let center = CGPoint(x: point.x + cornerRadius * cos(angle + .pi / 2),y: point.y + cornerRadius * sin(angle + .pi / 2))
  47. addArc(withCenter: center,radius: cornerRadius,startAngle: angle - .pi / 2,endAngle: angle + theta - .pi / 2,clockwise: true)
  48.  
  49. point = currentPoint
  50. angle += theta
  51. }
  52.  
  53. close()
  54.  
  55. self.lineWidth = lineWidth // in case we're going to use CoreGraphics to stroke path,rather than CAShapeLayer
  56. lineJoinStyle = .round
  57. }
  58.  
  59. }

对于Swift 2的演绎,请参阅previous revision of this answer.

猜你在找的iOS相关文章