- 通过 UIBezierPath 做一个中空的扫描器

今天在公司的代码里看到通过 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,奇偶。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。


- 通过 UIBezierPath 做一个中空的扫描器

时间: 2024-08-03 15:26:09

- 通过 UIBezierPath 做一个中空的扫描器的相关文章

React-Native做一个文本输入框组件

我又回来啦! 由于最近一直在做公司的项目,而且比较急.如今项目已经迭代到第三期,可以缓一缓了... 今天在公司里听前端的说,这个项目本来是用React-Native做的(去年10月份),但是做到一半发现坑太多,就中途放弃了,于是让我们android和iOS重新开发... 作为非常喜欢这个技术的我来说,表示相当的不服. 于是我打算利用闲暇时间做一个一模一样的出来,反正接口我都有(嘻嘻) 说实话,最近一直再用android做开发,而且时间也不宽裕,react-native有点生疏了. 好了,废话不多

做一个手机端页面时,遇到了一个奇怪的问题:字体的显示大小,与在CSS中指定的大小不一致

最近在做一个手机端页面时,遇到了一个奇怪的问题:字体的显示大小,与在CSS中指定的大小不一致.大家可以查看这个Demo(记得打开Chrome DevTools). 就如上图所示,你可以发现,原本指定的字体大小是24px,但是最终计算出来的却是53px,看到这诡异的结果,我心中暗骂一句:这什么鬼! 随后开始对问题各种排查:某个标签引起的?某个CSS引起的?又或者是某句JS代码引起的.通过一坨坨的删代码,发现貌似都不是.我不禁又骂,到底什么鬼!不过中间还是发现了一些端倪:当页面中的标签数量或者文本数

做一个微信语音点播系统

最近在做一个微信项目,接触到了微信公众平台.通过公众平台可以很方便的搭建一个功能完善的移动应用.昨天发现:开发者可使用手机号来申请接口测试帐号,体验高级接口. 这篇文章的应用将使用到高级接口中的语音识别,以及音乐回复接口.通过这两个接口,让大家体验一下语音点歌的魅力. 这个应用简单的来说:就是你向微信公众平台报一首歌名,微信公众平台返回这首歌曲给你听.本文将一步一步教你如何实现这个看似复杂的移动应用. 下面是我申请的测试账号的二维码,大家可以关注一下测试一下效果,不过测试账号的有效期只有一年,最

先做一个“小程序”——关于微信应用号的六大猜想

先做一个“小程序”——关于微信应用号的六大猜想 9月 21 日,苦等了9个多月的时间,应用号终于与我们见面了,命名为「小程序」. 01 为什么推出小程序? 考虑到小程序对整个APP市场的影响,毫无疑问会对现有的APP生态带来一定的冲击.但是,之所以推出小程序,最直接的原因可能是为了构建和扩充微信生态链,让微信更具开放性. 如我们所知,目前微信公众号分为三类: • 服务号,连接人和商品,目前很多电商企业,以及在微信端提供产品和服务的企业都用服务号. • 订阅号,微信官方的定位是阅读,连接人和资讯的

20151229:AJax :用类方式做一个查询

前台aspx代码不变,处理页面需要新建一个类,封装属性并在处理页面调用 新建类DB代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data;//引用命名空间 using System.Data.SqlClient; /// <summary> /// DB 的摘要说明 /// </summary> public class DB

今天来做一个PHP电影小爬虫。

今天来做一个PHP电影小爬虫.我们来利用simple_html_dom的采集数据实例,这是一个PHP的库,上手很容易.simple_html_dom 可以很好的帮助我们利用php解析html文档.通过这个php封装类可以很方便的解析html文档,对其中的html元素进行操作 (PHP5+以上版本)下载地址:https://github.com/samacs/simple_html_dom下面我们以 http://www.paopaotv.com 上的列表页 http://paopaotv.com

一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁

前续 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(一)——地:起因 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁 平行时空 在复制好上面那一行我就先停下来了,算是先占了个位置,虽然我知道大概要怎么写,不过感觉还是很乱. 我突然想到,既然那么纠结,那么混乱,那么不知所措,我们不如换个视角.记得高中时看过的为数不多的长篇小说<穆斯林的葬礼>,作者是:霍达(女),故事描写了两个发生在不同时代.有着不同的内容却又交错扭结的爱情悲剧,一个是“玉”的故事,一个是“月”

android如果用ListView做一个表格形式

效果图: 这样来写: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test); ListView list = (ListView)findViewById(R.id.lvLinks); SquareItemAdapter adapter = new SquareItemAdapter(this)

做一个聪明的前端开发者

那么什么是聪明者,就是打架不出拳,直接用刀砍,或者更牛逼的就开枪! 那么如何做一个聪明的前端开发者? 很显然,就是用工具代替手工,用自动代替手动! 那到底是用什么工具呢,如下: 前端开发工具 工具有点多,但是都非常简单,或许你已经安装并使用过一些了. git,版本控制系统 node,JS运行平台 npm,node的包管理 yo,脚手架 grunt,项目构建工具 bower,项目依赖包管理 git,http://git-scm.com/ 据说是一款很厉害的版本控制系统,类似SVN,不过本人还没有所