• iOS上图形和动画处理


    苹果公司在iOS和OS X上向开发者提供了强大的框架来处理图形和动画,这些框架和技术有:

    UIKit:高层次的框架,允许开发人员创建视图、窗口、按钮和其他UI相关的组件。它还将一些低级别的API引入到易于使用的高级别的API中。

    Quartz 2D:iOS上绘图的主要引擎,UIKit就使用Quartz。

    Core Graphics:它支持图形上下文、加载图像、绘制图像,等等。

    Core Animation:iOS上实现动画的框架。

    1 绘制文本

      public func drawAtPoint(point: CGPoint, withAttributes attrs: [String : AnyObject]?)

      public func drawInRect(rect: CGRect, withAttributes attrs: [String : AnyObject]?)

        override func drawRect(rect: CGRect) {
            
            let string: NSString = "Some String";
            
            let attr: [String: AnyObject] = [NSFontAttributeName: UIFont.init(name: "HelveticaNeue-Bold", size: 30)!,
                                             NSForegroundColorAttributeName: UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0),
                                             NSBackgroundColorAttributeName: UIColor.lightGrayColor()]
            
            string.drawAtPoint(CGPointMake(40, 180), withAttributes: attr)
            
            let string2: NSString = "I Learn Really Fast"
            
            string2.drawInRect(CGRectMake(40, 250, 100, 100), withAttributes: attr)
        }

     2 绘制图形

      UIKit帮助你轻松的绘制图像,你所需要做的是需要把你的图像加载在UIImage类的实例中。UIImage类提供了各种类方法和实例方法来加载图像。

       public func drawAtPoint(point: CGPoint) 

         public func drawInRect(rect: CGRect)

    override func drawRect(rect: CGRect) {
      let image = UIImage(named: "f015")
      image?.drawAtPoint(CGPointMake(40, 80))       //按照图片的原始大小绘制
            
      let image2 = UIImage(named: "f015")
      image2?.drawInRect(CGRectMake(40, 200, 10, 10))  //在矩形区域内绘制
    }

    3 绘制线条

      路径是由屏幕上一个或一系列点构成。路径和线条有很大的区别,路径可以包含很多线条,但线条不能包含很多路径。把路径当做一系列的点,就是这么简单。

      必须使用路径来绘制线条。指定起点和终点,然后要求Core Graphics来绘制路径。

      绘制线条的步骤:

      (1)为图形上下文选定一个颜色;

      (2)使用UIGraphicsGetCurrentContext函数获取图形上下文句柄;

      (3)使用CGContextSetLineWidth设置线条的宽度;

      (4)使用CGContextMoveToPoint过程设置线条的起点;

      (5)使用CGContextAddLineToPoint过程在图形上下文移动画笔来设置线条的终点;

      (6)使用CGContextStrokePath过程创建已设置好的路径。

    override func drawRect(rect: CGRect) {
            
            UIColor.blueColor().set()
            
            let context = UIGraphicsGetCurrentContext()
            
            CGContextSetLineWidth(context, 5.0)
         
    //.Miter:尖角,默认样式 .Round:圆角 .Bevel:平角 CGContextSetLineJoin(context, CGLineJoin.Round)
            CGContextMoveToPoint(context, 40, 80)
            CGContextAddLineToPoint(context, 80, 160)
            CGContextAddLineToPoint(context, 120, 80)
         CGContextStrokePath(context)
    }

    4 绘制路径

      路径属于正在绘制他们的图形上下文。路径没有边界(Boundary)或特定的形状,但路径有边界框(Boundary boxes)。Boundary和Boundary Boxes完全不一样,Boundary限制你在画布上哪些不可以用来绘画,而Boundary Boxes是包含了所有路径上的形状、点和其他已经绘制的对象额最小矩形。你可以在图形上下文中对路径进行填充,或者对它进行描边。下面是你会用到的一些方法:

      (1)CGPathCreateMutable函数:创建一个类型为CGMutablePathRef的可变路径,并返回其句柄。每次使用完这个路径,我们都应该为其做善后工作。

      (2)CGPathMoveToPoint过程:在路径上移动当前的位置到一个点。

      (3)CGPathAddLineToPoint过程:从当前的画笔位置向指定位置绘制线条。

      (4)CGContextAddPath过程:添加一个路径到图形上下文。

      (5)CGContextDrawPath过程:在图形上下文绘制给出的路径。

      (6)CGPathRelease过程:释放为路径句柄分配的内存。(ARC环境下不需要自己手动释放,系统会自己释放)

      (7)CGPathAddRect过程:向路径添加一个矩形。

      (8)kCGPathStroke:使用当前选定的描边颜色为路径描边。

      (9)kCGPathFill:使用当前选定的颜色填充路径所包围的区域。

      (10)kCGPathFillStroke:组合描边和填充。

        override func drawRect(rect: CGRect) {
            
            let path: CGMutablePathRef = CGPathCreateMutable()
            
            CGPathMoveToPoint(path, nil, rect.origin.x, rect.origin.y)
            CGPathAddLineToPoint(path, nil, rect.size.width, rect.size.height)
            
            CGPathMoveToPoint(path, nil, rect.size.width, rect.origin.y)
            CGPathAddLineToPoint(path, nil, rect.origin.x, rect.size.height)
            
            let context = UIGraphicsGetCurrentContext()
            
            CGContextAddPath(context, path)
            
            UIColor.brownColor().setStroke()
            
            CGContextDrawPath(context, CGPathDrawingMode.Stroke)
            
        }
    
        override func drawRect(rect: CGRect) {
            
            let path: CGMutablePathRef = CGPathCreateMutable()
            
            CGPathMoveToPoint(path, nil, 40, 80)
            CGPathAddLineToPoint(path, nil, 100, 150)
            CGPathAddLineToPoint(path, nil, 120, 100)
            CGPathAddLineToPoint(path, nil, 40, 80)
            
            let context = UIGraphicsGetCurrentContext()
            
            CGContextAddPath(context, path)
            
            UIColor.redColor().setStroke()
            UIColor.blueColor().setFill()
            
            CGContextDrawPath(context, CGPathDrawingMode.FillStroke)
            
        }

    5 绘制矩形

        override func drawRect(rect: CGRect) {
            
            let path: CGMutablePathRef = CGPathCreateMutable()
            
            CGPathAddRect(path, nil, CGRectMake(40, 80, 100, 100))  //绘制一个矩形

          CGPathAddRects(path, nil, [CGRectMake(40, 80, 100, 100), CGRectMake(40, 200, 100, 100)], 2)  //可以绘制多个矩形

            let context = UIGraphicsGetCurrentContext()
            
            CGContextAddPath(context, path)
            
            UIColor.brownColor().setStroke()
            UIColor.redColor().setFill()
            
            CGContextSetLineWidth(context, 5.0)
            
            CGContextDrawPath(context, CGPathDrawingMode.FillStroke)
        }

    6 为形状添加阴影

      (1)CGContextSetShadow:将会创建黑色或灰色阴影

      (2)CGContextSetShadowWithColor:可以自己设置阴影的颜色

        override func drawRect(rect: CGRect) {
            
            let context = UIGraphicsGetCurrentContext()
    
            CGContextSetShadow(context, CGSizeMake(5, 5), 3.0)
            
           // CGContextSetShadowWithColor(context, CGSizeMake(5, 5), 3.0, UIColor.lightGrayColor().CGColor)
            
            let path: CGMutablePathRef = CGPathCreateMutable()
            
            CGPathAddRect(path, nil, CGRectMake(40, 80, 100, 100))
            
            CGContextAddPath(context, path)
            
            UIColor(red: 0.2, green: 0.6, blue: 0.8, alpha: 1.0).setFill()
                
            CGContextDrawPath(context, CGPathDrawingMode.Fill)
        }

    7 创建和绘制渐变

        override func drawRect(rect: CGRect) {
            
            let context = UIGraphicsGetCurrentContext()
            
            CGContextSaveGState(context)
            
            let colorSpace: CGColorSpaceRef? = CGColorSpaceCreateDeviceRGB()
            
            //蓝色作为起点
            let startColor = UIColor.blueColor()
            
            let startColorComponents = CGColorGetComponents(startColor.CGColor)
            
            //橘色作为终点
            let closeColor = UIColor.orangeColor()
            
            let closeColorComponents = CGColorGetComponents(closeColor.CGColor)
            
            let colorComponents = [startColorComponents[0],
                                   startColorComponents[1],
                                   startColorComponents[2],
                                   startColorComponents[3],
                                   closeColorComponents[0],
                                   closeColorComponents[1],
                                   closeColorComponents[2],
                                   closeColorComponents[3]]
            
            let colorIndices: [CGFloat] = [0.0, 1.0]
            
            let gradient = CGGradientCreateWithColorComponents(colorSpace, colorComponents, colorIndices, 2)
            
            //起点
            let startPoint = CGPointMake(80.0, 80.0)
            //终点
            let closePoint = CGPointMake(250.0, 80.0)
            
            //.DrawsAfterEndLocation:扩展整个渐变到渐变的终点之后的所有点
            //.DrawsBeforeStartLocation:扩展整个渐变到渐变的起点之前的所有点
            CGContextDrawLinearGradient(context, gradient, startPoint, closePoint, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
            
            CGContextRestoreGState(context)
            
        }

     8 平移图形上下文的形状

      第一种方法:CGPathAddRect方法的第二个参数是一个CGAffineTransform类型的变换对象。

        override func drawRect(rect: CGRect) {
    
            //平移图形上下文的形状//第一种方法:CGPathAddRect方法的第二个参数是一个CGAffineTransform类型的变换对象        
            let path = CGPathCreateMutable()
            let rectangle = CGRectMake(10, 80, 200, 300)
            var transform = CGAffineTransformMakeTranslation(100, 0)
            
            CGPathAddRect(path, &transform, rectangle)
            let context = UIGraphicsGetCurrentContext()
            CGContextAddPath(context, path)
            
            UIColor.purpleColor().setStroke()
            UIColor.blueColor().setFill()
            
            CGContextSetLineWidth(context, 5.0)
            
            CGContextDrawPath(context, .FillStroke)
      }

      第二种方法:通过CGContextTransformCTM过程对图形上下文应用变换,这将把一个平移变换应用到当前变换矩阵(CTM:current transformation matrix)。把CTM认为是它设置了你的图形上下文的中心,是它把你绘制的每个点投射到屏幕上。通过改变CTM的配置,强制把所有绘制在图形上下文的形状转移到画布上的另一个地方。

        override func drawRect(rect: CGRect) {
    //平移图形上下文的形状//第二种方法:通过CGContextTransformCTM过程对图形上下文应用变换,这将把一个平移变换应用到当前变换矩阵(CTM:current transformation matrix)。把CTM认为是它设置了你的图形上下文的中心,是它把你绘制的每个点投射到屏幕上。通过改变CTM的配置,强制把所有绘制在图形上下文的形状转移到画布上的另一个地方。 let path = CGPathCreateMutable() let rectangle = CGRectMake(10, 80, 200, 300) CGPathAddRect(path, nil, rectangle) let context = UIGraphicsGetCurrentContext() CGContextSaveGState(context) CGContextTranslateCTM(context, 100, 0) CGContextAddPath(context, path) CGContextSetLineWidth(context, 5.0) UIColor.purpleColor().setStroke() UIColor.blueColor().setFill()
    CGContextDrawPath(context, .FillStroke)
      }

    9 缩放图形上下文的形状

      同上两种方法。

      第一种方法:var transform = CGAffineTransformMakeScale(1.0, 0.5)

      第二种方法:CGContextScaleCTM(context, 1, 0.5)

    10 旋转图形上下文的形状

      同上两种方法。

      第一种方法:var transform = CGAffineTransformMakeRotation(-CGFloat(M_2_PI)/2.0)

      第二种方法:CGContextRotateCTM(context, -CGFloat(M_2_PI)/2.0)

    11 动画--移动视图、缩放视图、旋转视图

      在iOS上有各种方式可以实现动画:在一个较低的层次提供了这种能力,在更高的层次也提供这种能力。我们可以获得的最高层次的动画能力是通过UIKit。UIKit中包括一些Core Animation的较低层次的功能,并且包装成非常简洁的API供我们使用。

      UIKit中实现动画的起点是调用UIView类的类方法beginAnimations:context:。其第一个参数是一个可选的动画的名字,第二个是一个可选的上下文,在之后传递给动画的委托方法时你可以获得它。

      在你通过beginAnimations:context:方法开始一个动画之后,它实际上不会马上执行,而是直到你调用UIView类的commitAnimation类方法。在beginAnimation:context:和commitAnimation之间,你对一个视图对象的计算将在commitAnimation被调用之后开始进行动画。

      使用UIKit执行动画时常用的方法:

      (1)beginAnimations:context:开始一个动画块。调用这个类方法之后,你对视图任何动画属性的改变,都会在动画块提交之后形成动画。

      (2)setAnimationDuration:以秒为单位设置动画的持续时间。

      (3)setAnimationDelegate:设置一个对象来接受动画开始之前、动画期间或动画结束之后发生的各种事件的委托对象。设置一个委托对象不会立即开始发送动画委托消息。你必须对视图对象使用其他的setter方法来告诉UIKit你的委托对象中的哪个选择器(selector)要接受哪些委托消息。

      (4)setAnimationDidStopSelector:设置动画完成时委托对象中用过被调用的方法。这个方法按照以下顺序接受是哪个参数:

    • NSString类型的动画标识:它包含在动画开始时传给beginAnimations:context:方法的动画标识。
    • 一个“已完成”的标识,NSNumber类型:此参数包含一个由NSNumber包装的布尔值,如果动画在被其他代码停止之前能够完整地执行,运行时(Runtime)将它设置为YES。如果这个值被设置为NO,意味着动画在完后之前被中断了。
    • 一个void *类型的上下文:这是动画开始时传给beginAnimations:context:方法的上下文。

      (5)setAnimationWillStartSeletor:设置动画即将开始时委托对象中被顶选择器,参数通上。 

      (6)setAnimationDelay: 设置一个动画启动的延迟时间。 

      (7)setAnimationRepeatCount:设置一个动画块需要重复它的动画次数。 

    UIView.beginAnimations("iconAnimation", context: nil)
    UIView.setAnimationDuration(3.0) 
    //可以直接通过改变frame来移动视图
    self.iconImage.frame = CGRectMake(UIScreen.mainScreen().bounds.width - 100, UIScreen.mainScreen().bounds.height - 100, 100, 100)
    //缩放视图--缩放后,视图的中心不变        
    self.iconImage.layer.setAffineTransform(CGAffineTransformMakeScale(2.0, 2.0))
    //旋转视图       
    self.iconImage.layer.setAffineTransform(CGAffineTransformMakeRotation(CGFloat(M_PI)))
            
    UIView.commitAnimations()
  • 相关阅读:
    luogu P2827 蚯蚓
    CHOI1001/1002 火车进出栈问题
    hdoj4699 Editor
    反弹shell监控
    AppScan 9.0.3.6 crack
    Spectre & Meltdown Checker – CPU芯片漏洞检查脚本Linux版
    Microsoft IIS WebDav 'ScStoragePathFromUrl' Remote Buffer Overflow (CVE-2017-7269)
    Shodan新手使用指南
    The Art of Subdomain Enumeration (转)
    DDOS攻击方式总结 (转)
  • 原文地址:https://www.cnblogs.com/muzijie/p/5842843.html
Copyright © 2020-2023  润新知