切割额六边形

最近做项目,项目中大量出现六边形视图,包括基本的视图和按钮。详情查看Demo

在这里插入图片描述

这种实现效果一般有两种
第一种:让美工小姐姐切图,使用iOS图片切片技术拉伸图片,但这种很有局限性,背景颜色,边框颜色,还有边框样式不一样就用切一种图片,非常不方便。
第二种:那就是使用贝塞尔曲线进行切割。这种方法优点非常明显,不管修改成什么颜色,边框样式都是可以的。
接下来我们来说一下第二种

切割六边形

1.首先我们来切割一下直角的六边形


在这里插入图片描述
extension UIView {
    
    /// 切割六边形(没有弧度)
    public func setSixRightBorder() {
        /// 获取切割路径
        let maskPath = getSexanglePath()
        
        /// 创建切割路径Layer
        let maskLayer = CAShapeLayer()
        maskLayer.path = maskPath.cgPath
        self.layer.mask = maskLayer
    }
    
    private func getSexanglePath() -> UIBezierPath {
        let PI = CGFloat.pi
        /// 整个视图的框
        let allWidth = self.bounds.size.width
        /// 整个视图的高
        let allHeight = self.bounds.size.height
        /// 我们假设六边形的内角是120度
        let operateAngle = PI - 2*PI/3
        /// 线段b的长度为
        let bLength = allHeight/2
        /// 所以如图线段a的长度为
        let aLength = bLength/tan(operateAngle)
        /// P1点坐标为
        let p1 = CGPoint(x: allWidth - aLength, y: 0)
        /// P2点坐标为
        let p2 = CGPoint(x: allWidth, y: bLength)
        /// P2点坐标为
        let p3 = CGPoint(x: p1.x, y: allHeight)
        /// 同理可求出 对应左边的3个点坐标
        let p4 = CGPoint(x: aLength, y: allHeight)
        /// P5点坐标为
        let p5 = CGPoint(x: 0, y: bLength)
        /// P6点坐标为
        let p6 = CGPoint(x: aLength, y: 0)
        
        let path = UIBezierPath()
        path.move(to: p1)
        path.addLine(to: p2)
        path.addLine(to: p3)
        path.addLine(to: p4)
        path.addLine(to: p5)
        path.addLine(to: p6)
        path.close()
        return path
    }
}
20210309224845823.png

这里可以看到留个角是没有圆弧的,那么如何产生最上方效果图中的形状呢,接下来我们开始讲解

切割带弧度的六边形

20210309230212914.png

这里是核心代码

/// 定义PI值
        let PI = CGFloat(Double.pi)
        /// 弧度半径
        let radius: CGFloat = radius
        /// 视图的宽
        let allWidth = self.bounds.size.width
        /// 视图的高
        let allHeight = self.bounds.size.height
        /// 视图高度的一半
        let LayerHeigh = self.bounds.size.height/2
        /// 六边形的一个内角度数(这里默认是正六边形 所以一个角是120度)
        let sixDegree: CGFloat = PI*2/3
        let operateDegree:CGFloat = PI - sixDegree
        /// 圆弧与上边线的切点 到左上角的距离
        let distance = radius / tan(operateDegree)
        /// 左边定点到左上角之间的X狙击
        let maxDistance = LayerHeigh / tan(operateDegree)
        
        
        /// 计算第一个点
        let firstPointX = allWidth - (maxDistance + distance)
        let firstPoint = CGPoint(x: firstPointX, y: 0)
        
        /// 计算第二个点
        let secondPointX = firstPointX + distance + distance*cos(operateDegree)
        let secondPointY = distance*sin(operateDegree)
        let secondPoint = CGPoint(x: secondPointX, y: secondPointY)
        
        /// 计算第三个点
        let thirdPointX = allWidth - distance*cos(operateDegree)
        let thirdPointY = LayerHeigh - distance*sin(operateDegree)
        let thirdPoint = CGPoint(x: thirdPointX, y: thirdPointY)
        
        /// 计算第四个点
        let fourPointY = LayerHeigh + distance*sin(operateDegree)
        let fourPoint = CGPoint(x: thirdPointX, y: fourPointY)
        
        /// 计算第五个点
        let fivePointY = allHeight - secondPoint.y
        let fivePoint = CGPoint(x: secondPoint.x, y: fivePointY)
        
        /// 计算第六个点
        let sixPoint = CGPoint(x: firstPoint.x, y: allHeight)
        
        /// 第七个点
        let sevenPointX = maxDistance + distance
        let sevenPoint = CGPoint(x: sevenPointX, y: allHeight)
        
        /// 第八个点
        let eightPointX = maxDistance  - distance*cos(operateDegree)
        let eightPoint = CGPoint(x: eightPointX, y: fivePointY)
        
        /// 第九个点
        let ninePointX = distance*cos(operateDegree)
        let ninePoint = CGPoint(x: ninePointX, y: fourPointY)
        
        /// 第十个点
        let tenPoint = CGPoint(x: ninePointX, y: thirdPointY)
        
        /// 第十一个点
        let elevenPoint = CGPoint(x: eightPoint.x, y: secondPoint.y)
        
        /// 第十二个点
        let twelvePoint = CGPoint(x: sevenPoint.x, y: 0)
        
        /// 第一个圆弧圆心坐标
        let center1 = CGPoint(x: firstPoint.x, y: radius)
        /// 第二个圆弧圆心坐标
        let center2 = CGPoint(x: allWidth - distance/cos(operateDegree), y: LayerHeigh)
        /// 第三个圆弧圆心坐标
        let center3 = CGPoint(x: sixPoint.x, y: allHeight - radius)
        /// 第四个圆弧圆心坐标
        let center4 = CGPoint(x: sevenPoint.x, y: allHeight - radius)
        /// 第五个圆弧圆心坐标
        let center5 = CGPoint(x: distance/cos(operateDegree), y: LayerHeigh)
        /// 第六个圆弧圆心坐标
        let center6 = CGPoint(x: twelvePoint.x, y: radius)
        let path = UIBezierPath()
        path.move(to: firstPoint)
        path.addArc(withCenter: center1, radius: radius, startAngle: CGFloat(-PI/2), endAngle: operateDegree - PI/2, clockwise: true)
        path.addLine(to: thirdPoint)
        path.addArc(withCenter: center2, radius: radius, startAngle: CGFloat(-operateDegree/2), endAngle: operateDegree/2, clockwise: true)
        path.addLine(to: fivePoint)
        path.addArc(withCenter: center3, radius: radius, startAngle: operateDegree/2, endAngle: PI/2, clockwise: true)
        path.addLine(to: sevenPoint)
        path.addArc(withCenter: center4, radius: radius, startAngle: PI/2, endAngle: PI/2 + operateDegree, clockwise: true)
        path.addLine(to: ninePoint)
        path.addArc(withCenter: center5, radius: radius, startAngle: PI - operateDegree/2, endAngle: PI + operateDegree/2, clockwise: true)
        path.addLine(to: elevenPoint)
        path.addArc(withCenter: center6, radius: radius, startAngle: PI + operateDegree/2, endAngle: PI*3/2, clockwise: true)
        path.close()

效果图


20210309233032124.png

末尾附上Demo。如果你觉得有帮助,请多多Star,好了结束撒花,大家加油❀❀❀❀❀

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容