Ios 如何使用六边形遮罩圆角UIImage
我正在尝试将一个六边形遮罩添加到我已经成功制作的UIImage中。然而,我无法圆的六边形面具的双方。我想添加cell.profilePic.layer.cornerRadius=10;我想这样做,但事实并非如此 这是我的密码:Ios 如何使用六边形遮罩圆角UIImage,ios,objective-c,uiimage,Ios,Objective C,Uiimage,我正在尝试将一个六边形遮罩添加到我已经成功制作的UIImage中。然而,我无法圆的六边形面具的双方。我想添加cell.profilePic.layer.cornerRadius=10;我想这样做,但事实并非如此 这是我的密码: CGRect rect = cell.profilePic.frame; CAShapeLayer *hexagonMask = [CAShapeLayer layer]; CAShapeLayer *hexagonBorder = [CAShapeLayer
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];
有什么想法吗
谢谢也许您必须绕过边框和遮罩的角,而不是图像视图的角
hexagonMask.cornerRadius = hexagonBorder.cornerRadius = 10.0;
可以定义具有圆角的六边形路径(手动定义该路径),然后将其应用为遮罩和边框子层:
CGFloat lineWidth = 5.0;
UIBezierPath *path = [UIBezierPath polygonInRect:self.imageView.bounds
sides:6
lineWidth:lineWidth
cornerRadius:30];
// mask for the image view
CAShapeLayer *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 layer
CAShapeLayer *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
及
与
扩展UIBezierPath{
///为具有圆角的正多边形创建UIBezierPath
///
///-参数rect:应在其中创建路径的正方形的CGRect。
///-参数边:多边形的边数(例如6=六边形;8=八角形等)。
///-参数lineWidth:多边形周围笔划的宽度。多边形将被插入,以便笔划保持在上面的正方形内。默认值1。
///-参数cornerRadius:圆角时应用的半径。默认值为0。
便利初始化(polygonIn rect:CGRect,sides:Int,线宽:CGFloat=1,拐角半径:CGFloat=0){
self.init()
设θ=2*.pi/CGFloat(边)//在每个拐角处转弯多少
let offset=cornerRadius*tan(θ/2)//开始圆角的偏移量
设squareWidth=min(rect.width,rect.height)//正方形的宽度
//计算多边形边的长度
变量长度=平方宽度-线宽
如果边%4!=0{//如果不处理所有边都是正方形的多边形。。。
长度=长度*cos(θ/2)+偏移/2/…在正方形内的圆内偏移
}
设边长=长度*tan(θ/2)
//如果要开始旋转90度,请使用这些线,而不是以下两条线:
//
//变量点=CGPoint(x:rect.midX-长度/2,y:rect.midY+边长/2-偏移)
//变量角度=-CGFloat.pi/2.0
//如果要开始旋转180度,请使用这些线,而不是以下两条线:
//
//var point=CGPoint(x:rect.midX-sideLength/2+偏移量,y:rect.midY-length/2)
//变量角度=CGFloat(0)
var point=CGPoint(x:rect.midX+sideLength/2-偏移,y:rect.midY+length/2)
变量角度=CGFloat.pi
移动(到:点)
//绘制多边形的边和圆角
对于0..<边中的uu{
点=CGPoint(x:point.x+(边长-偏移*2)*cos(角度),y:point.y+(边长-偏移*2)*sin(角度))
添加线(到:点)
设中心=CGPoint(x:point.x+拐角半径*cos(角度+.pi/2),y:point.y+拐角半径*sin(角度+.pi/2))
添加弧(带中心:中心,半径:角半径,起始角:角度-.pi/2,终止角:角度+θ-.pi/2,顺时针:真)
点=当前点
角度+=θ
}
关闭()
self.lineWidth=lineWidth//如果我们要使用CoreGraphics来绘制路径,而不是CAShapeLayer
lineJoinStyle=.round
}
}
有关Swift 2格式副本,请参见。这里是Swift的roundedPolygon方法的转换
func roundedPolygonPathWithRect(square: CGRect, lineWidth: Float, sides: Int, cornerRadius: Float) -> UIBezierPath {
var path = UIBezierPath()
let theta = Float(2.0 * M_PI) / Float(sides)
let offset = cornerRadius * tanf(theta / 2.0)
let squareWidth = Float(min(square.size.width, square.size.height))
var length = squareWidth - lineWidth
if sides % 4 != 0 {
length = length * cosf(theta / 2.0) + offset / 2.0
}
var sideLength = length * tanf(theta / 2.0)
var point = CGPointMake(CGFloat((squareWidth / 2.0) + (sideLength / 2.0) - offset), CGFloat(squareWidth - (squareWidth - length) / 2.0))
var angle = Float(M_PI)
path.moveToPoint(point)
for var side = 0; side < sides; side++ {
let x = Float(point.x) + (sideLength - offset * 2.0) * cosf(angle)
let y = Float(point.y) + (sideLength - offset * 2.0) * sinf(angle)
point = CGPointMake(CGFloat(x), CGFloat(y))
path.addLineToPoint(point)
let centerX = Float(point.x) + cornerRadius * cosf(angle + Float(M_PI_2))
let centerY = Float(point.y) + cornerRadius * sinf(angle + Float(M_PI_2))
var center = CGPointMake(CGFloat(centerX), CGFloat(centerY))
let startAngle = CGFloat(angle) - CGFloat(M_PI_2)
let endAngle = CGFloat(angle) + CGFloat(theta) - CGFloat(M_PI_2)
path.addArcWithCenter(center, radius: CGFloat(cornerRadius), startAngle: startAngle, endAngle: endAngle, clockwise: true)
point = path.currentPoint
angle += theta
}
path.closePath()
return path
}
func roundedPolygonPathWithRect(正方形:CGRect,线宽:Float,边:Int,角半径:Float)->UIBezierPath{
var path=UIBezierPath()
设θ=浮动(2.0*M_π)/浮动(侧面)
let offset=转角半径*tanf(θ/2.0)
让squareWidth=浮动(最小值(square.size.width,square.size.height))
变量长度=平方宽度-线宽
如果边%4!=0{
长度=长度*余弦(θ/2.0)+偏移量/2.0
}
var边长=长度*tanf(θ/2.0)
var point=CGPointMake(CGFloat((平方宽度/2.0)+(边长/2.0)-偏移),CGFloat(平方宽度-(平方宽度-长度)/2.0))
可变角度=浮动(M_PI)
路径.移动点(点)
对于var侧=0;侧<侧;侧++{
设x=浮点(点x)+(边长-偏移*2.0)*余弦(角度)
设y=浮点(点y)+(边长-偏移*2.0)*sinf(角度)
点=CGPointMake(CGFloat(x)、CGFloat(y))
path.addLineToPoint(点)
设centerX=浮动(点x)+转角半径*cosf(角度+浮动(M_PI_2))
设中心y=浮动(点y)+转角半径*sinf(角度+浮动(M_PI_2))
var center=CGPointMake(CGFloat(centerX)、CGFloat(centerY))
设startAngle=CGFloat(角度)-CGFloat(M_PI_2)
设endAngle=CGFloat(角度)+CGFloat(θ)-CGFloat(M_PI_2)
path.addArcWithCenter(中心,半径:CGFloat(拐角半径),星形缠结:星形缠结,端角:端角,顺时针:true)
点=路径。当前点
角度+=θ
}
path.closePath()
返回路径
}
这是的swift 3版本
let线宽:CGFloat=5.0
let path=UIBezierPath(roundedPolygonPathWithRect:self.bounds,线宽:线宽,边数:6,角半径:12)
let mask=CAShapeLayer()
mask.path=path.cgPath
mask.lineWidth=线宽
mask.strokeColor=UIColor.clear.cgColor
mask.fillColor=UIColor.white.cgColor
self.layer.mask=掩码
let border=CAShapeLayer()
border.path=path.cgPath
border.lineWidth=线宽
border.strokeColor=UIColor.black.cgColor
border.fillColor=UIColor.clear.cgColor
self.layer.addSublayer(边框)
扩展UIBezierPath{
便利初始化(roundedPolygonPathWithRect:CGRect,线宽:cGloat,
let lineWidth: CGFloat = 5
let path = UIBezierPath(polygonIn: imageView.bounds, sides: 6, lineWidth: lineWidth, cornerRadius: 30)
let mask = CAShapeLayer()
mask.path = path.cgPath
mask.lineWidth = lineWidth
mask.strokeColor = UIColor.clear.cgColor
mask.fillColor = UIColor.white.cgColor
imageView.layer.mask = mask
let border = CAShapeLayer()
border.path = path.cgPath
border.lineWidth = lineWidth
border.strokeColor = UIColor.black.cgColor
border.fillColor = UIColor.clear.cgColor
imageView.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 * .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.width, rect.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
}
}
func roundedPolygonPathWithRect(square: CGRect, lineWidth: Float, sides: Int, cornerRadius: Float) -> UIBezierPath {
var path = UIBezierPath()
let theta = Float(2.0 * M_PI) / Float(sides)
let offset = cornerRadius * tanf(theta / 2.0)
let squareWidth = Float(min(square.size.width, square.size.height))
var length = squareWidth - lineWidth
if sides % 4 != 0 {
length = length * cosf(theta / 2.0) + offset / 2.0
}
var sideLength = length * tanf(theta / 2.0)
var point = CGPointMake(CGFloat((squareWidth / 2.0) + (sideLength / 2.0) - offset), CGFloat(squareWidth - (squareWidth - length) / 2.0))
var angle = Float(M_PI)
path.moveToPoint(point)
for var side = 0; side < sides; side++ {
let x = Float(point.x) + (sideLength - offset * 2.0) * cosf(angle)
let y = Float(point.y) + (sideLength - offset * 2.0) * sinf(angle)
point = CGPointMake(CGFloat(x), CGFloat(y))
path.addLineToPoint(point)
let centerX = Float(point.x) + cornerRadius * cosf(angle + Float(M_PI_2))
let centerY = Float(point.y) + cornerRadius * sinf(angle + Float(M_PI_2))
var center = CGPointMake(CGFloat(centerX), CGFloat(centerY))
let startAngle = CGFloat(angle) - CGFloat(M_PI_2)
let endAngle = CGFloat(angle) + CGFloat(theta) - CGFloat(M_PI_2)
path.addArcWithCenter(center, radius: CGFloat(cornerRadius), startAngle: startAngle, endAngle: endAngle, clockwise: true)
point = path.currentPoint
angle += theta
}
path.closePath()
return path
}
let lineWidth: CGFloat = 5.0
let path = UIBezierPath(roundedPolygonPathWithRect: self.bounds, lineWidth: lineWidth, sides: 6, cornerRadius: 12)
let mask = CAShapeLayer()
mask.path = path.cgPath
mask.lineWidth = lineWidth
mask.strokeColor = UIColor.clear.cgColor
mask.fillColor = UIColor.white.cgColor
self.layer.mask = mask
let border = CAShapeLayer()
border.path = path.cgPath
border.lineWidth = lineWidth
border.strokeColor = UIColor.black.cgColor
border.fillColor = UIColor.clear.cgColor
self.layer.addSublayer(border)
extension UIBezierPath {
convenience init(roundedPolygonPathWithRect rect: CGRect, lineWidth: CGFloat, sides: NSInteger, cornerRadius: CGFloat) {
self.init()
let theta = CGFloat(2.0 * M_PI) / CGFloat(sides)
let offSet = CGFloat(cornerRadius) / CGFloat(tan(theta/2.0))
let squareWidth = min(rect.size.width, rect.size.height)
var length = squareWidth - lineWidth
if sides%4 != 0 {
length = length * CGFloat(cos(theta / 2.0)) + offSet/2.0
}
let sideLength = length * CGFloat(tan(theta / 2.0))
var point = CGPoint(x: squareWidth / 2.0 + sideLength / 2.0 - offSet, y: squareWidth - (squareWidth - length) / 2.0)
var angle = CGFloat(M_PI)
move(to: point)
for _ in 0 ..< sides {
point = CGPoint(x: point.x + CGFloat(sideLength - offSet * 2.0) * CGFloat(cos(angle)), y: point.y + CGFloat(sideLength - offSet * 2.0) * CGFloat(sin(angle)))
addLine(to: point)
let center = CGPoint(x: point.x + cornerRadius * CGFloat(cos(angle + CGFloat(M_PI_2))), y: point.y + cornerRadius * CGFloat(sin(angle + CGFloat(M_PI_2))))
addArc(withCenter: center, radius:CGFloat(cornerRadius), startAngle:angle - CGFloat(M_PI_2), endAngle:angle + theta - CGFloat(M_PI_2), clockwise:true)
point = currentPoint // we don't have to calculate where the arc ended ... UIBezierPath did that for us
angle += theta
}
close()
}
}