UIBezierPath和CAShapeLayer创建不规则View(Swift 3.0)
最近一个朋友在做图片处理的 App,想要实现类似 MOLDIV App
拼图的UI
效果(如何创建不规则的 view
),就问我有什么想法。我首先想到的就是 UIBezierPath
+CAShapeLayer
的方式,为了验证自己的想法,写了一个小 demo
。
效果图:
![](http://upload-images.jianshu.io/upload_images/4661706-6c3650cdcf820f52.gif?imageMogr2/auto-orient/strip)
实现思路
正常情况下我们创建的 view
都是矩形的。但是我们知道 view
的内容显示靠的是 layer
层,所以可以通过修改 layer
层来实现。代码如下:
func drawMaskLayer() {guard (points != nil) else {return}let bezierPath1 = UIBezierPath()bezierPath1.move(to: points![0])for index in 1..<points!.count {bezierPath1.addLine(to: points![index])}bezierPath1.addLine(to: points![0])let shapeLayer = CAShapeLayer()shapeLayer.path = bezierPath1.cgPathself.layer.mask = shapeLayer}
通过这种方式我们可以创建出任何的多边形的 view
。通过这种方式我们可以很容易的创建出上图所示的 UI
布局。但是我们这个时候会发现,当有触摸点在 view
透明的地方时,触摸事件并不能传递给被它遮挡的 view
上,所以需要重写 func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
方法来判断何时响应。代码如下:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {if points != nil {if (super.hitTest(point, with: event) == scrollV) {print(self,point)print(points!)let isInner = isInnerView(with: point)if isInner {return self.scrollV}else {return nil}}}else {return super.hitTest(point, with: event)}return nil}
那么何时响应,何时不响应呢?应该是如果触摸点在我们绘制的 view
范围内响应,之外的不相应。那么这个时候就需要判断一个点在是否在多边形内,本 demo 使用 射线法。
fileprivate func isInnerView(with point: CGPoint) -> Bool {let pX = point.x , pY = point.yvar flag = falsevar oldIndex = points!.count - 1for newIndex in 0..<points!.count {let newX = points![newIndex].xlet newY = points![newIndex].ylet oldX = points![oldIndex].xlet oldY = points![oldIndex].y// 点与多边形顶点重合if (pX == newX && pY == newY) || (pX == oldX && pY == oldY) {return false}// 判断线段两端点是否在射线两侧if (oldY > pY && newY < pY) || (oldY < pY && newY > pY) {// 线段上与射线 Y 坐标相同的点的 X 坐标let x = newX + (pY - newY) * (oldX - newX) / (oldY - newY)// 点在多边形的边上if(x == pX) {return false}// 射线穿过多边形的边界if(x > pX) {flag = !flag}}oldIndex = newIndex}// 射线穿过多边形边界的次数为奇数时点在多边形内return flag ? true : false}
到了这里 demo
也就基本完成了。希望对需要的人有帮助,有什么不对的欢迎指正。
源代码:
ZCFJointView
环境:
Xcode 8.2 、Swift 3.0
参考资料:
射线法
UIBezierPath和CAShapeLayer创建不规则View(Swift 3.0)相关推荐
- UIBezierPath和CAShapeLayer画直线、CGContextRef画直线两种方案
在view的相关方法中可直接使用UIBezierPath和CAShapeLayer画图形- (void)makeBezierPath {/**CAShapeLayer属于QuartzCore框架,继承 ...
- 放肆地使用UIBezierPath和CAShapeLayer画各种图形
CAShapeLayer 是 CALayer 的子类,但是比 CALayer 更灵活,可以画出各种图形,当然,你也可以使用其他方式来画,随你. 杂谈 在 CAShapeLayer 中,也可以像 CAL ...
- 放肆的使用UIBezierPath和CAShapeLayer画各种图形
CAShapeLayer 是 CALayer 的子类,但是比 CALayer 更灵活,可以画出各种图形,当然,你也可以使用其他方式来画,随你. 杂谈 在 CAShapeLayer 中,也可以像 CAL ...
- 放肆的使用UIBezierPath和CAShapeLayer画各种图形(含仿微信视频眼镜Demo)
Collection/Bookmark/Share for width under 768px CAShapeLayer 是 CALayer 的子类,但是比 CALayer 更灵活,可以画出各种图形, ...
- 使用CSS 3创建不规则图形
2019独角兽企业重金招聘Python工程师标准>>> 前言 CSS 创建复杂图形的技术即将会被广泛支持,并且应用到实际项目中.本篇文章的目的是为大家开启它的冰山一角.我希望这篇文章 ...
- 一起谈.NET技术,C#创建不规则窗体的几种方式
现在,C#创建不规则窗体不是一件难事,下面总结一下: 一.自定义窗体,一般为规则的图形,如圆.椭圆等. 做法:重写Form1_Paint事件(Form1是窗体的名字),最简单的一种情况如下 ...
- Swift基础:创建第一个Swift工程:Swift的基本语法
苹果公司在今年的WWDC大会上,除了发布了iOS8和Max OS X 10.10之外,还发布了一个新的编程语言Swift.不得不说,Swift有较大的转变,也使编程变得更加容易了,下面介绍了Swift ...
- Android官方开发文档Training系列课程中文版:创建自定义View之View的创建
原文地址:http://android.xsoftlab.net/training/custom-views/index.html 引言 Android框架含有大量的View类,这些类用来显示各式各样 ...
- android 动态创建view,react-native动态创建Android View 无效果
问题描述 react-native动态创建Android View 无效果,我想在react-native里面直接点击函数进行创建,也就是通过module中的方法创建View 问题出现的环境背景及自己 ...
最新文章
- 在Unity3d中调用外部程序及批处理文件
- IKE IPSEC ×××
- .net core项目部署到centos7
- motan yar php,motan学习笔记 六 opentracing Brave+zipkin实现-Go语言中文社区
- acwing2058. 笨拙的手指(进制转换)
- [渝粤题库]西北工业大学统计学
- 计算机组成原理AB什么运算,计算机组成原理运算器实验.doc
- Pentium 4处理器架构/微架构/流水线 (3) - NetBurst微架构
- SQL Server 数据库维护脚本合集[007]-删除数据库所有用户表数据
- c++ java setobjectarrayelement_java中jni的使用:C/C++操作java中的数组
- 【网络安全工程师面试合集】— 渗透资源 操作系统大合集
- C#可逆加密-Rijndael算法
- plsql查询不显示结果_管理NVivo的查询结果
- 快速突破面试算法(内含从简到难的高频题型目录及每题的详解,已经归类整理好并外带博主的免费答疑)
- UI中经常出现的下拉框下拉自动筛选效果的实现
- mysql linux 安装包下载_mysql官网下载linux版本安装包
- 关于达芬奇调色台的那些事儿
- 嘉应大学黄林鑫计算机学院,林鑫-中国科学院大学-UCAS
- 安卓隐藏摄像_隐藏拍摄app
- Vue关于pdf展示问题——第三方电子签章不能正常展示