今天在公司的代码里看到通过 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. Hibernate与iBATIS的比较

    1.出身 hibernate 是当前最流行的o/r mapping框架,它出身于sf.net,现在已经成为jboss的一部分了. ibatis 是另外一种优秀的o/r mapping框架,目前属于ap ...

  2. RAW模板开发--入口文件官方规范

    每个人都有自己的习惯,为了RAW模板能进一步推广,使RAW模板的开发也更有条理,所以写了这个文章. 规范1格式: <?php /*RAW标记声明-start*/ /*RAW标记声明-over*/ ...

  3. 【转】android windowSoftInputMode

    android:windowSoftInputMode activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性. 这个属性能影响两件事情: [一] ...

  4. IM与工作信息流整合

    IM与工作信息流整合,希望减轻用户“信息”负担   从36氪此前的<“明道”现在推出个人免费版本,是怎样的逻辑?>一 文中,我们可以了解到,国内现在的协作产品设计思路主要有两种:一种是像t ...

  5. IC卡,ID卡,M1卡,射频卡

    一般把可读可写,频率是13.56MHz的射频卡称为IC卡,IC卡可以写入数据, 只能读,频率是125KHz的射频卡称为ID卡, M1卡是NXP公司的S50卡的一种叫法,国内的复旦F08,达华的TKS5 ...

  6. Protel99se教程二:使用protel99se原理图绘制

    使用protel99se绘制原理图,首先要先设置一下显示网格这一项,这个可以根据个人习惯,并不是一定需要这样的,在prote99se的界面的View菜下,将visible Grid选中或取消,可以选择 ...

  7. HDU 1720 A+B Coming

    #include <string> #include <cstdio> #include <iostream> using namespace std; int c ...

  8. JAVA GUI学习 - JProgressBar进度条组件摘录

    public class JProgressBarTest extends JFrame{ public JProgressBarTest() { super(); setTitle("表格 ...

  9. c 整数的逆序输出 输入3,2就算 2+22+222的结果

    #include<stdio.h> #include<math.h> //整数逆序输出 void nixu() { int num,i; i = ; scanf("% ...

  10. ajax不执行success回调而是执行了error回调

    最近在看jQuery的API文档,在使用到jQuery的ajax时,如果指定了dataType为json,老是不执行success回调,而是执行了error回调函数.   附上代码如下: JScrip ...