- 通过 UIBezierPath 做一个中空的扫描器
一个 通过 扫描器
2023-09-11 14:17:59 时间
今天在公司的代码里看到通过 UIBezierPath
绘制 CALayer 然后实现中空的正方形,感觉还挺有意思的,简单记录一下 UIBezierPath
这个东西。
一条线
我们自定义一个 BezierView 继承自 UIView ,并重写它的 drawRect
方法实现绘图操作。
import UIKit
class BezierView: UIView {
override func drawRect(rect: CGRect) {
super.drawRect(rect);
var myBezier = UIBezierPath()
myBezier.moveToPoint(CGPoint(x: 100, y: 100))
myBezier.addLineToPoint(CGPoint(x: 200, y: 100))
UIColor.orangeColor().setStroke()
myBezier.stroke()
}
}
两条线
也就是先 moveToPoint
然后再 addLineToPoint
一次:
import UIKit
class BezierView: UIView {
override func drawRect(rect: CGRect) {
super.drawRect(rect);
var myBezier = UIBezierPath()
myBezier.moveToPoint(CGPoint(x: 100, y: 100))
myBezier.addLineToPoint(CGPoint(x: 200, y: 100))
myBezier.moveToPoint(CGPoint(x: 100, y: 200))
myBezier.addLineToPoint(CGPoint(x: 200, y: 200))
UIColor.orangeColor().setStroke()
myBezier.stroke()
}
}
一个圆
我们可以通过下面的方法绘制一个圆弧:
var bezier1 = UIBezierPath()
bezier1.addArcWithCenter(CGPointMake(100, 300), radius: 50, startAngle: 0, endAngle: 1.0, clockwise: true)
bezier1.stroke()
其中,startAngle
是以 x 轴正方向为起点,clockwise
则是用来标记是否为顺时针方向。
加个框
stroke
是画线,fill
是填充。所以实心圆可以这么画:
UIColor.redColor().setFill()
UIColor.greenColor().setStroke()
var bezier2 = UIBezierPath()
bezier2.addArcWithCenter(CGPointMake(100, 300), radius: 50, startAngle: 0, endAngle: 20, clockwise: true)
bezier2.lineWidth = 10
bezier2.stroke()
bezier2.fill()
空心圆
其实当初看到 UIBezierPath 是因为公司的项目里用这个实现了一个中间是透明正方形的黑色蒙版,用在了二维码扫描上。接下来就试着做一个黑色的蒙版,然后中间有一个透明的正方形。
先来看看 mask
的用法:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var path = UIBezierPath()
path.addArcWithCenter(view.center, radius: 100, startAngle: 0, endAngle: CGFloat(M_PI), clockwise: true)
path.closePath()
var mask = CAShapeLayer()
mask.path = path.CGPath
view.layer.mask = mask
}
}
接下来我们可以简单的实现以下这个中空的效果:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let imageView = UIImageView(image: UIImage(named: "avatar"))
imageView.center = view.center
view.addSubview(imageView)
let maskLayer = CALayer()
maskLayer.frame = view.frame
maskLayer.backgroundColor = UIColor.blackColor().CGColor
maskLayer.opacity = 0.6
view.layer.addSublayer(maskLayer)
let rectSize = CGFloat(100)
let shapeLayer = CAShapeLayer()
shapeLayer.frame = view.layer.frame
var path = UIBezierPath(rect: CGRectMake((view.frame.width-rectSize)/2, (view.frame.height-rectSize)/2, rectSize, rectSize))
path.appendPath(UIBezierPath(rect: view.layer.frame))
shapeLayer.path = path.CGPath
shapeLayer.fillRule = kCAFillRuleEvenOdd
maskLayer.mask = shapeLayer
}
}
简单记录一下 fillRule
,它有两种值:
-
kCAFillRuleNonZero,非零。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径 的交点情况。从0开始计数,路径从左向右穿过射线则计数加1,从右向左穿过射线则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为 在内部。
-
kCAFillRuleEvenOdd,奇偶。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。
相关文章
- 一个极其高效的虚拟机内存冗余消除机制:UKSM
- 【实战】如何通过html+css+mysql+php来快速的制作动态网页(以制作一个博客网站为列)
- mysql通过sql语句如何批量去掉某一个表中某一个字段的下面的相同部分字符串
- 编写一个面向管道的函数
- 测试一个伟大的产品
- PHP获取数组的一个元素
- 在自己的电脑上通过IIS发布一个网页
- 通过一个具体的例子,讲解 SAP BDC 技术的使用步骤
- 通过一个具体的例子,深入了解 SAP UI5 控件数据双向绑定的工作原理和问题排查方法试读版
- ABAP Web Service 调用的一个例子
- 通过一个具体的例子,讲解 SAP BDC 技术的使用步骤试读版
- 通过一个简单的ABAP报表窥探ABAP内存分配和管理机制
- 介绍一个快速找出 Visual Studio Code 代码多余空格的扩展 - trailing space
- 在自己的电脑上通过IIS发布一个网页
- 再谈C#采集,一个绕过高强度安全验证的采集方案?方案很Low,慎入
- Chrome开发者工具一个有用的快捷键组合:Ctrl+Shift+E
- SAP OData 服务在 gateway 层出错,应该如何处理?通过一个错误消息 Query XXX is invalid or contains errors 来举例说明
- 在自己的电脑上通过IIS发布一个网页
- 编程笔试(解析及代码实现):猴子吃桃。猴子第一天吃了若干个桃子,当即吃了一半,还不解馋,又多吃了一个…的C++、Java、Python、C#等语言代码实现
- 判断一个字符串是否全部不相同
- Java JDK 1.8 下载及其版本说明 8u202(最后一个免费版)
- MATLAB | 一个贼简单的粒子圣诞树
- Tomcat通过配置一个虚拟路径管理web工程
- jQuery EasyUI一个基于 jQuery 的框架(创建网页所需的一切)
- 爬虫日记(105):Twisted:怎么样处理一个函数同步代码返回和异步对象返回
- 年薪百万,7年测试经验:守在一个还算不错的赛道,慢慢积累,等风来
- 创建一个动态Web项目: