iOS 动画Animation - 5:UIBezier
首先说明:这是一系列文章,參考本专题下其它的文章有助于你对本文的理解。
在之前的bolg中大家会发现总是会出现UIBezier,可是我也没有做过多介绍,今天就集中介绍一下UIBezier。首先。UIBezier的内容比較多,我今天介绍的也不是UIBezier的所有,可是大部分经常使用到的我都会介绍一下。至于其它的,请大家參考官方文档。
由于今天的内容比較多。也可能有些地方不是非常easy理解,我会尽量的把他介绍的看起来简单一些,方便学习。
首先上一张图,你就会看到今天要讲到的内容
这就是今天要讲到的内容。我会教大家将如图所看到的的图形都绘制下来。
首先我们须要创建一个UIView类。对这个UIView类做绘制操作
我创建的UIView类教PathView,然后在ViewController里创建他的对象
//创建一个PathView
let pathView = PathView()
pathView.frame = CGRect(x: 50, y: 0, width: 350, height: 550)
view.addSubview(pathView)
然后剩下的操作都是在这个PathView里了,在drawRect方法里对视图进行绘制
一次贝塞尔曲线
一次贝塞尔曲线比較简单,相信大家都看得懂
五边形
func creatPentagonPath() {
let path = UIBezierPath()
path.lineWidth = 2.0 //线宽
//设置起点
path.moveToPoint(CGPoint(x: 70.0, y: 20.0))
//设置拐角点
path.addLineToPoint(CGPoint(x: 120.0, y: 40.0))
path.addLineToPoint(CGPoint(x: 100.0, y: 90.0))
path.addLineToPoint(CGPoint(x: 40.0, y: 90.0))
path.addLineToPoint(CGPoint(x: 20.0, y: 40.0))
//最后闭合
path.closePath()
path.stroke()//描边样式
//path.fill()//填充样式
}
解释:这是最简单的一个UIBezier。path.moveToPoint()和path.closePath()作为起点和闭合曲线是必须的,中间的addLineToPoint就是加入各个点。在这里加入的五个点组成的图形是一个五边形。
path.stroke()和path.fill()差别就是一个是描边样式,一个是填充样式。之前的bolg里有讲到strok和fill的差别。
矩形
矩形有专门的初始化方法。不用再手动的绘制
func creatRectanglePath() {
//创建bezier路径
let path = UIBezierPath(rect: CGRect(x: 220, y: 30, width: 100, height: 50))
path.lineCapStyle = .Round //线类型
path.lineJoinStyle = .Miter //拐角类型
path.lineWidth = 2.0//设置线宽
path.stroke()//描边样式
//path.fill()//填充样式
}
解释:这个也简单。rect就是矩形。path.lineCapStyle是线类型,path.lineJoinStyle是拐角类型,跟之前将CAShapeLayer里有一些属性比較类似。能够參考,链接:iOS 动画Animation-4-3: CALayer子类:CAShapeLayer
椭圆
也能够用来画圆。内切于正方形的时候就是圆了
func creatOvalPath() {
//画出来的椭圆为ovalInRect画出的矩形的内切椭圆
let path = UIBezierPath(ovalInRect: CGRect(x: 20, y: 120, width: 100, height: 50))
path.lineWidth = 2
path.fill()
}
解释:这个有没有看起来更简单呢,就初始化方式不一样而已,ovalInRect就代表的是椭圆而且是内切与rect的椭圆
圆弧
func creatArcPath() {
let path = UIBezierPath(arcCenter: CGPoint(x: 270, y: 120), radius: 50, startAngle: 0, endAngle: CGFloat(M_PI), clockwise: true)
path.lineWidth = 2
path.stroke()
}
解释:当中的參数分别指定:这段圆弧的中心,半径,開始角度,结束角度,是否顺时针方向。
二次贝塞尔曲线
这就比一次贝塞尔曲线略微复杂一下了。二次贝塞尔曲线的特点就是会有一个控制点
func creatQuadCurvePath() {
let path = UIBezierPath()
//设置起点
path.moveToPoint(CGPoint(x: 20, y: 210))
//參数分别指终点,中间控制点
path.addQuadCurveToPoint(CGPoint(x: 120, y: 210), controlPoint: CGPoint(x: 70, y: 180))
//加入圆弧, 參数依次为中心点, 半径, 開始角度, 结束角度, 是否顺时针
path.addArcWithCenter(CGPoint(x: 70, y: 210), radius: 50, startAngle: 0.0, endAngle: CGFloat(M_PI), clockwise: true)
path.lineWidth = 2
path.stroke()
}
解释:感觉凝视都写的非常具体了path.addQuadCurveToPoint这就是二次贝塞尔曲线。是有一个控制点(第二个參数)控制这条曲线的弯曲程度,第一个參数是终点,当然另一个path.moveToPoint作为起点。
通过以下这张图。具体大家都清晰了二次贝塞尔曲线的各个參数是作什么用的了
三次贝塞尔曲线
func creatCurvePath() {
let path = UIBezierPath()
//起点
path.moveToPoint(CGPoint(x: 220, y: 230))
//參数分别指终点,中间控制点
path.addCurveToPoint(CGPoint(x: 320, y: 220), controlPoint1: CGPoint(x: 250, y: 200), controlPoint2: CGPoint(x: 290, y: 250))
path.lineWidth = 2
path.stroke()
}
解释:能够看到三次贝塞尔曲线就是比二次贝塞尔曲线多了一个控制点。关系图例如以下图所看到的
以下再简单的涉足一下Core Graphics
单一改动CGPath
func creatSingleCGPath() {
//创建可变CGPath
let cgPath = CGPathCreateMutable()
CGPathAddEllipseInRect(cgPath, nil, CGRect(x: 20, y: 270, width: 100, height: 50))
CGPathAddEllipseInRect(cgPath, nil, CGRect(x: 45, y: 282.5, width: 50, height: 25))
let path = UIBezierPath()
path.CGPath = cgPath
path.usesEvenOddFillRule = true
path.lineWidth = 2
path.stroke()
// CGPathRelease(cgPath);假设是OC须要运行这句代码
}
解释:创建可变Path通过Core Graphics函数来改动Path
CGPath与UIBezierPath混合使用
func creatMixCGPathAndUIBezierPath() {
//创建贝塞尔曲线
let path = UIBezierPath(ovalInRect: CGRect(x: 220, y: 270, width: 100, height: 50))
//获取CGPath
let cgPath = path.CGPath
//copy给可变CGPath
let mutablePath = CGPathCreateMutableCopy(cgPath)! as CGMutablePathRef
//设置起点
CGPathMoveToPoint(mutablePath, nil, 245, 295)
//加入曲线
//參数cp1x实际上是controlPoint1.x的缩写,所以參数为,控制点1,控制点2,终点
CGPathAddCurveToPoint(mutablePath, nil, 255, 270, 285, 320, 295, 295)
//其它函数
/*
//加入直线
CGPathAddLineToPoint(<#T##path: CGMutablePath?##CGMutablePath?#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##x: CGFloat##CGFloat#>, <#T##y: CGFloat##CGFloat#>)
//參数1,点的数组,參数2:count要绘制的点的个数
CGPathAddLines(<#T##path: CGMutablePath?
##CGMutablePath?
#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##points: UnsafePointer<CGPoint>##UnsafePointer<CGPoint>#>, <#T##count: Int##Int#>)
//加入路径
CGPathAddPath(<#T##path1: CGMutablePath?##CGMutablePath?#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##path2: CGPath?
##CGPath?
#>)
//加入二次路径
CGPathAddQuadCurveToPoint(<#T##path: CGMutablePath?
##CGMutablePath?#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##cpx: CGFloat##CGFloat#>, <#T##cpy: CGFloat##CGFloat#>, <#T##x: CGFloat##CGFloat#>, <#T##y: CGFloat##CGFloat#>)
//加入矩形
CGPathAddRect(<#T##path: CGMutablePath?##CGMutablePath?
#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##rect: CGRect##CGRect#>)
CGPathAddRects(<#T##path: CGMutablePath?##CGMutablePath?#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##rects: UnsafePointer<CGRect>##UnsafePointer<CGRect>#>, <#T##count: Int##Int#>)
CGPathAddRoundedRect(<#T##path: CGMutablePath?##CGMutablePath?#>, <#T##transform: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##rect: CGRect##CGRect#>, <#T##cornerWidth: CGFloat##CGFloat#>, <#T##cornerHeight: CGFloat##CGFloat#>)
//加入圆弧
CGPathAddArc(<#T##path: CGMutablePath?
##CGMutablePath?#>, <#T##m: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##x: CGFloat##CGFloat#>, <#T##y: CGFloat##CGFloat#>, <#T##radius: CGFloat##CGFloat#>, <#T##startAngle: CGFloat##CGFloat#>, <#T##endAngle: CGFloat##CGFloat#>, <#T##clockwise: Bool##Bool#>)
CGPathAddRelativeArc(<#T##path: CGMutablePath?
##CGMutablePath?#>, <#T##matrix: UnsafePointer<CGAffineTransform>##UnsafePointer<CGAffineTransform>#>, <#T##x: CGFloat##CGFloat#>, <#T##y: CGFloat##CGFloat#>, <#T##radius: CGFloat##CGFloat#>, <#T##startAngle: CGFloat##CGFloat#>, <#T##delta: CGFloat##CGFloat#>)
*/
path.CGPath = mutablePath
path.lineWidth = 2
path.stroke()
}
解释:这里内容比較多。我就不一一解释了。事实上方法内容跟上面介绍的都比較类似。
參数也基本和上面介绍的一样。细致看的话都能看懂什么意思。
内容控制(附加)
func setUpContext() {
let path = UIBezierPath(ovalInRect: CGRect(x: 20, y: 350, width: 100, height: 50))
UIColor.redColor().setStroke()
UIColor.orangeColor().setFill()
let ref = UIGraphicsGetCurrentContext()
//内容平移
CGContextTranslateCTM(ref, 20, 20)
//内容旋转
//由于我把所有图形画在同一个视图中,anchorPoint并不是当前椭圆的中心, 所以旋转后当前椭圆会偏离所在位置
CGContextRotateCTM(ref, CGFloat(-M_PI_4/4));
//内容缩放
CGContextScaleCTM(ref, 0.8, 1.0)
path.lineWidth = 2
path.fill()
path.stroke()
}
解释:事实上关于内容控制的又会是一大块的内容,我就不在这里做具体介绍了。
加大。昨天忘了将Demo放上来了,真是对不起各位观众了,尽管我知道没有多少回头客,可是还得道下歉。Demo地址
iOS 动画Animation - 5:UIBezier的更多相关文章
- 转 iOS Core Animation 动画 入门学习(一)基础
iOS Core Animation 动画 入门学习(一)基础 reference:https://developer.apple.com/library/ios/documentation/Coco ...
- (转)iOS动画Core Animation
文章转载:http://blog.sina.com.cn/s/blog_7b9d64af0101b8nh.html 在iOS中动画实现技术主要是:Core Animation. Core Animat ...
- iOS - Core Animation 核心动画
1.UIView 动画 具体讲解见 iOS - UIView 动画 2.UIImageView 动画 具体讲解见 iOS - UIImageView 动画 3.CADisplayLink 定时器 具体 ...
- IOS动画(Core Animation)总结 (参考多方文章)
一.简介 iOS 动画主要是指Core Animation框架.官方使用文档地址为:Core Animation Guide. Core Animation是IOS和OS X平台上负责图形渲染与动画的 ...
- 简析iOS动画原理及实现——Core Animation
本文转载至 http://www.tuicool.com/articles/e2qaYjA 原文 https://tech.imdada.cn/2016/06/21/ios-core-animati ...
- iOS Core Animation学习总结(3)--动画的基本类型
一. CABasicAnimation (基础动画) 移位: CABasicAnimation *animation = [CABasicAnimation animation]; //keyPath ...
- 解析 iOS 动画原理与实现
这篇文章不会教大家如何实现一个具体的动画效果,我会从动画的本质出发,来说说 iOS 动画的原理与实现方式. 什么是动画 动画,顾名思义,就是能“动”的画.人的眼睛对图像有短暂的记忆效应,所以当眼睛看到 ...
- iOS动画原理
1. iOS动画原理 本质:动画对象(这里是UIView)的状态,基于时间变化的反应 分类:可以分为显式动画(关键帧动画和逐帧动画)和隐式动画 关键帧和逐帧总结:关键帧动画的实现方式,只需要修改某个属 ...
- iOS 动画基础
原文:http://www.cnblogs.com/lujianwenance/p/5733846.html 今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学, ...
随机推荐
- 利用fabric批量安装kvm虚拟机及其xp
公司一批PC机需要安装多个虚拟机跑任务,搞来搞去决定用centos7安装KVM来跑.于是先折腾了一下午,利用早先搭建好的cobbler给PC机安装OS.然后fabric批量部署. 环境:centos7 ...
- java的selenium环境搭建
1.下载jdk1.8 环境变量我的博客有我就不说 selenium下载地址:http://npm.taobao.org/mirrors/selenium 2.下 ...
- HDU-2087 剪花布条 字符串问题 KMP算法 查匹配子串
题目链接:https://cn.vjudge.net/problem/HDU-2087 题意 中文题咯 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条, ...
- 【PRML学习笔记】第四章:分类的线性模型
一.基础概念 线性分类模型:决策面(decision boundary)是输入向量的线性函数 目标类别的表示"1 of K" :$ t = (0,1,0,0,0)^T$ 二.分类问 ...
- C语言编译和链接
编译链接是使用高级语言编程所必须的操作,一个源程序只有经过编译.链接操作以后才可以变成计算机可以理解并执行的二进制可执行文件. 编译是指根据用户写的源程序代码,经过词法和语法分析,将高级语言编写的代码 ...
- Ask DevOps: Top 5 Business Alternatives to Splunk
https://siliconangle.com/blog/2012/11/20/ask-devops-top-5-business-alternatives-to-splunk/
- 洛谷 P1990 覆盖墙壁
P1990 覆盖墙壁 题目描述 你有一个长为N宽为2的墙壁,给你两种砖头:一个长2宽1,另一个是L型覆盖3个单元的砖头.如下图: 0 0 0 00 砖头可以旋转,两种砖头可以无限制提供.你的任务是计算 ...
- 在android中,编译的项目使用到第三方jar的导入方法 终极版!
1,在android系统环境中编译自己的项目时,往往会用到第三方jar包.这些jar包在eclipse中加入编译,一路畅通,由于eclipse已经帮助你配置好了.可是当把这个项目复制到系统环境中编译时 ...
- Ext4.1 chart的使用
var reportsPanel = Ext.create('Ext.panel.Panel', { id:'reportsPanel', layout: 'fit', tbar: [{ ...
- Android Stuido 好卡怎么办?不要急,兄弟来教你
近期使用Android studio 开发app,编译的时候特别卡,常常卡死.我的机器 i3 + 8G,按道理来说流畅的跑个androidstudio还是绰绰有余的... 于是在各大论坛寻找解决方式, ...