zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    LeetCode Merge Two Sorted Lists 归并排序
    LeetCode Add Binary 两个二进制数相加
    LeetCode Climbing Stairs 爬楼梯
    034 Search for a Range 搜索范围
    033 Search in Rotated Sorted Array 搜索旋转排序数组
    032 Longest Valid Parentheses 最长有效括号
    031 Next Permutation 下一个排列
    030 Substring with Concatenation of All Words 与所有单词相关联的字串
    029 Divide Two Integers 两数相除
    028 Implement strStr() 实现 strStr()
  • 原文地址:https://www.cnblogs.com/muzijie/p/5842843.html
Copyright © 2011-2022 走看看