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的同学, ...
随机推荐
- shell基础编程
首先要注意的是,Ubuntu里的shell的sh和bash命令是有区别的 如下所示,Ubuntu下的sh指向的dash程序,而bash是dash的增强版,一些bash上能执行的程序在dash上不行 如 ...
- php报错权限设置
<?php //禁用错误报告 error_reporting(0); //报告运行时错误 error_reporting(E_ERROR | E_WARNING | E_PARSE); //报告 ...
- Sublime Text编辑器配置Python解释器简易教程
前天在微信上遇到一个小伙伴问我一个关于Sublime text配置Python解释器的问题,可能是初学者,对这方面还不是很懂,想使用快捷键但是徒劳一场,因为缺少Python解释器,直接按下快捷键Ctr ...
- layui层级
zIndex:layer.zIndex, success : function(layero){ var zIndex = layer.index; $(layero).css(‘z-index’,z ...
- 洛谷3627 [APIO2009]抢掠计划
题目描述 输入格式: 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点 ...
- [洛谷P1750]KC喝咖啡
题目大意:给你n个物品,每个物品有一个价值$v_i$和一个时间$t_i$,要你取m个物品,使得他们的美味度($\frac{\sum v_i}{\sum t_i}$)最大,求这个美味度. 解题思路:由于 ...
- 纯净版linux (debian)挂载VirtualBox共享文件夹
使用的虚拟机版本是:VirtualBox-5.2.8-121009 使用的linux版本是:Linux debian 4.9.0-7-amd64 tty 1. 开始配置 1.1:打开虚拟机设置,打开你 ...
- [SDOI2008]郁闷的小J(分块)
[SDOI2008]郁闷的小J 题目描述 小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危 ...
- 题解 P3372 【【模板】线段树1 】(zkw)
看了一下题解里的zkw线段树,感觉讲的不是很清楚啊(可能有清楚的但是我没翻到,望大佬勿怪). 决定自己写一篇...希望大家能看明白... zkw线段树是一种优秀的非递归线段树,速度比普通线段树快两道三 ...
- 洛谷 P1332 血色先锋队
P1332 血色先锋队 题目描述 巫妖王的天灾军团终于卷土重来,血色十字军组织了一支先锋军前往诺森德大陆对抗天灾军团,以及一切沾有亡灵气息的生物.孤立于联盟和部落的血色先锋军很快就遭到了天灾军团的重重 ...