今天在公司的代码里看到通过 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 做一个中空的扫描器的更多相关文章

  1. 【技巧】使用weeman来做一个钓鱼网页

    本文来自网友836834283 对玄魂工作室的投稿. 工具项目地址:https://github.com/Hypsurus/weeman/ 克隆地址:https://github.com/Hypsur ...

  2. 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

    最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...

  3. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  4. 做一个 App 前需要考虑的几件事

    做一个 App 前需要考虑的几件事  来源:limboy的博客   随着工具链的完善,语言的升级以及各种优质教程的涌现,做一个 App 的成本也越来越低了.尽管如此,有些事情最好前期就做起来,避免当 ...

  5. 有了lisk,为什么我们还要做一个Asch?

    0 前言 首先要声明一点,我们和我们的一些朋友都是lisk的投资人和支持者,我们也相信lisk会成功. 事实上,lisk已经成功了一半,目前在区块链领域融资金额排行第二,仅次于以太坊. 那为什么我们还 ...

  6. 做一个阅读管理APP

    背景 由于最近在看的书有点多,所以一直想找一个能够管理阅读进度的书(鄙人记性不是很好,两天不看就忘了)可惜Android平台上一直找不到合适的APP: 有没有读书进度管理的网站或软件啊? 有没有记录读 ...

  7. 微软云创益大赛获奖团队风采:做一个中国特色的.Net源代码社区

    为了强化云技术,落地云应用,彰显云价值,微软(中国)携手中国计算机报举办了“微软Cloud OS第二届云创益大赛”.本届大赛历时111天,共吸引了6647位个人组选手回答了70,078道题,59支参赛 ...

  8. 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。

    用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...

  9. 【 D3.js 入门系列 --- 5.1 】 做一个带坐标轴和标签的图表

    前面几节讲解了图标.坐标轴.比例等等,这一节整合这些内容做一个实用的图表.结果图如下: 代码如下所示: <html> <head> <meta charset=" ...

随机推荐

  1. iOS解析数据判断nil NULL Null的方法

    + (BOOL)isNil:(NSObject*)obj { if (obj == nil || obj == NULL) { return YES; } if ([obj isKindOfClass ...

  2. CSS hank

    CSS hank CSS hank是为了让CSS代码兼容不同浏览器,也可以通过CSS hank为不同的浏览器设置不同的CSS样式. CSS hank的3种表现形式: 类内部hank IE6能识别下划线 ...

  3. Java学习之异常处理

    在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出),Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性.       Throwabl ...

  4. Liunx 环境下vsftpd的三种实现方法(超详细参数)

    以下文章介绍Liunx 环境下vsftpd的三种实现方法 ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.0.3.tar.gz,目前已经到2.0.3版本.假 ...

  5. Special Subsequence(离散化线段树+dp)

    Special Subsequence Time Limit: 5 Seconds      Memory Limit: 32768 KB There a sequence S with n inte ...

  6. php:检测用户当前浏览器是否为IE浏览器

    /** * 检测用户当前浏览器 * @return boolean 是否ie浏览器 */ function chk_ie_browser() { $userbrowser = $_SERVER['HT ...

  7. TCP传输连接建立与释放详解

    一直以来有许多读者朋友对TCP的传输连接建立和释放过程不是很理解,而这又是几乎网络认证中必考的知识点,包括软考.CCNA\CCNP.H3CNA\H3CNE等,为此再把笔者年度巨作,广受好评的——< ...

  8. POJ 1236 Network of Schools(强连通 Tarjan+缩点)

    POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意:  给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...

  9. 利用jxl读取excel合并的单元格的一个小样例

    工作中我们可能要把Excel文件的记录保存到数据库, 今天我用jxl读取Excel文件时遇到了合并格的问题,记录例如以下: 如Excel文件例如以下: watermark/2/text/aHR0cDo ...

  10. ActionScript3游戏中的图像编程(连载十七)

    总文件夹:http://blog.csdn.net/iloveas2014/article/details/38304477 1.3.3 HSB与RGB之间的互转公式及HSL和HSV对色彩属性理解的异 ...