• iOS 动画Animation


    首先说明:这是一系列文章,參考本专题下其它的文章有助于你对本文的理解。

    在之前的bolg中大家会发现总是会出现UIBezier,可是我也没有做过多介绍,今天就集中介绍一下UIBezier。首先。UIBezier的内容比較多,我今天介绍的也不是UIBezier的所有,可是大部分经常使用到的我都会介绍一下。至于其它的,请大家參考官方文档。

    由于今天的内容比較多。也可能有些地方不是非常easy理解,我会尽量的把他介绍的看起来简单一些,方便学习。

    首先上一张图,你就会看到今天要讲到的内容
    这里写图片描写叙述

    这就是今天要讲到的内容。我会教大家将如图所看到的的图形都绘制下来。

    首先我们须要创建一个UIView类。对这个UIView类做绘制操作

    这里写图片描写叙述

    我创建的UIView类教PathView,然后在ViewController里创建他的对象

    //创建一个PathView
    let pathView = PathView()
    pathView.frame = CGRect(x: 50, y: 0,  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,  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,  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,  100, height: 50))
            CGPathAddEllipseInRect(cgPath, nil, CGRect(x: 45, y: 282.5,  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,  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,  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地址

  • 相关阅读:
    uC/OS II原理分析及源码阅读(一)
    并查集回顾
    js中ascii码的转换
    NS2中trace文件分析
    NS2中修改载波侦听范围和传输范围
    ubuntu wubi非在线快速安装
    用康托展开实现全排列(STL、itertools)
    日期的各种计算
    求约数的个数(约数个数定理)
    Parallel.js初探续集
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8443287.html
Copyright © 2020-2023  润新知