zoukankan      html  css  js  c++  java
  • Playground动手玩 (在OSx 10.9.3 、Xcode 6 beta环境下测试playground,只能用Swift语言)

    0 本文的程序例子

      先说说代码例子,文章最后面有个程序,直接将代码拷贝到新建的playground文件中,就可以这样展示和调试了

      

     

        普通的代码编写过程中直接就在右栏中显示执行结果,点击执行结果右边有两个小图标,一个眼睛的图标,可以直观看到图形或数值(当前状态),另外一个是+号,可以回溯历史数据和变量之间的相关性。 点击+号就可以看到上面的跷跷板和变量执行图,还有右下角的时间轴,可以手动拖放回滚。

     

      1、什么是playground?playground是Xcode的新的调试程序的一个工具,它提供灵活的数据展示方式,弥补了我们之前调试程序的手段的不足之处,它支持QuickLook多样式调试显示,不用添加测试代码、也不用按Run执行程序,就可以直观地查看运行情况,实时查看变量,可以直接查看的类型有:Color类型、String类型、Image类型、View类型、数据等等,可以自已开发动态展示的代码(实现接口),使用XCPCaptureValue函数观察和回溯动态过程。

      有什么情况不用playground ?游乐场虽好,但毕竟还是游乐场,目前它不支持界面交互,也就是说暂时无法在Playground上玩你实现的游戏。只能看不能动,还有就是无法直接执行你的App程序,毕竟它不是模拟器。

         

      2、playground有什么好处呢?从学习的用途上来说,它便于练习Swift,对初学编程的人来讲更是有好处,不用整天按F6,F7,也不用等虚拟机运行程序看结果。对熟悉的开发者来讲,它便于调试核心算法,测试一些涉及绘制的程序、图像处理等一些又要看得见又不太方便用其他测试代码做到的

        对使用开发环境的人来说,Playground有利于学习和尝试各种API,因为你不用为此设立项目,带着一个文件就可以到处跑

      3、 用个例子说明playground怎么用,我们直接上代码吧,我从WWDC2014会上展示的内容好象没有找到代码下载,所以先从视频上抄下一些代码,动手测试一下。这些代码只要直接拷到playground里面去就可以了,我们只要做几个事情

        a、在文件头引入 import XCPlayground,用于下文实现playground的一些接口

        b、实现func XCPCaptureValue<T>(identifier: String, value: T)用于显示程序执行过程中的历史数据,你可以用时间轴回滚,同时也看到变量与变量之间的关系。

        c、实现func XCPShowView(identifier: String, view: NSView),直接显示程序的动态执行过程,两个小孩在跷跷板上玩,然后你看到跷跷板变角度变量的历史过程和实现手动操作回滚

    代码如下:

     import Cocoa

    import QuartzCore

    import XCPlayground

     class PlaygroundIconView:NSView {

        let backgroundLayer=CAShapeLayer()

        let seesawBaseLayer=CAShapeLayer()

        let seesawLayer=CAShapeLayer()

        init(){

            super.init(frame:NSRect(x:0,y:0,568,height:568))

            

            backgroundLayer.frame=self.bounds

            seesawBaseLayer.frame=NSRect(x:254,y:124,60,height:111)

            seesawLayer.frame=NSRect(x:40,y:197, 488,height:30)

            

            setUpBackgroundLayer()

            setUpSeesawBaseLayer()

            setUpSeesawLayer()

            

            self.wantsLayer=true

            

            self.layer.addSublayer(backgroundLayer)

            self.layer.addSublayer(seesawBaseLayer)

            self.layer.addSublayer(seesawLayer)

        }

        

        func setUpBackgroundLayer(){

            let lineWidth=9.0

            let backgroundPath=NSBezierPath(roundedRect:NSInsetRect(bounds, lineWidth/2, lineWidth/2),xRadius:35.0,yRadius:35.0)

            backgroundPath.lineWidth=lineWidth

            

            backgroundLayer.strokeColor=NSColor.playgroundIconStrokeColor().CGColor

            backgroundLayer.fillColor=NSColor.playgroundIconFillColoer().CGColor

            backgroundLayer.lineWidth=lineWidth

            

            backgroundLayer.path=CGPathFromNSBezierPath(backgroundPath)

        }

        

        func setUpSeesawBaseLayer(){

         

            let seesawBasePath=NSBezierPath()

            

            

            let rectHeight:Int=50;

            

            

            seesawBasePath.moveToPoint(NSPoint(x:0,y:rectHeight))

            seesawBasePath.lineToPoint(NSPoint(x:seesawBaseLayer.bounds.width/2,y:seesawBaseLayer.bounds.height))

            seesawBasePath.lineToPoint(NSPoint(x:seesawBaseLayer.bounds.width,y:50))

             seesawBaseLayer.fillColor=NSColor.whiteColor().CGColor

            seesawBaseLayer.path=CGPathFromNSBezierPath(seesawBasePath)

        }

        

        func setUpSeesawLayer(){

           

            let createChildLayer:()->CAShapeLayer={

                let childLayer=CAShapeLayer()

                let headPath=NSBezierPath(ovalInRect:NSRect(x:60,y:150,49,height:49))

                

                let bodyPath=NSBezierPath()

                

                bodyPath.moveToPoint(NSPoint(x:58,y:155))

                bodyPath.lineToPoint(NSPoint(x:88,y:140))

                bodyPath.lineToPoint(NSPoint(x:126,y:100))

                

                bodyPath.lineToPoint(NSPoint(x:120,y:90))

                

                bodyPath.lineToPoint(NSPoint(x:125,y:71))

                

                bodyPath.lineToPoint(NSPoint(x:113,y:71))

                

                bodyPath.lineToPoint(NSPoint(x:112,y:94))

                bodyPath.lineToPoint(NSPoint(x:83,y:113))

                bodyPath.lineToPoint(NSPoint(x:68,y:94))

                

                bodyPath.lineToPoint(NSPoint(x:97,y:70))

                

                bodyPath.lineToPoint(NSPoint(x:122,y:12))

                    

                bodyPath.lineToPoint(NSPoint(x:98,y:0))

                

                bodyPath.lineToPoint(NSPoint(x:64,y:41))

                

                bodyPath.lineToPoint(NSPoint(x:7,y:71))

                

                bodyPath.lineToPoint(NSPoint(x:0,y:94))

                

                bodyPath.moveToPoint(NSPoint(x:58,y:155))

                

                let childPath=NSBezierPath()

                

                childPath.appendBezierPath(headPath)

                childPath.appendBezierPath(bodyPath)

                

                childLayer.fillColor=NSColor.whiteColor().CGColor

                childLayer.path=CGPathFromNSBezierPath(childPath)

                

                return childLayer

            }

        

        

        let leftChildLayer = createChildLayer()

        let rightChildLayer = createChildLayer()

        

        rightChildLayer.transform=CATransform3DMakeRotation(M_PI,0.0,0.0,1.0)

        rightChildLayer.geometryFlipped=true

        let benchLayer = CALayer()

        

        benchLayer.frame=NSRect(x:0,y:41,self.seesawLayer.bounds.width,height:30)

        

        benchLayer.backgroundColor=NSColor.whiteColor().CGColor

        

        leftChildLayer.frame=NSRect(x:25,y:0,126,height:200)

        rightChildLayer.frame=NSRect(x:488-(126+25),y:0,126,height:200)

        

        seesawLayer.addSublayer(leftChildLayer)

        seesawLayer.addSublayer(rightChildLayer)

        seesawLayer.addSublayer(benchLayer)

        

        seesawLayer.delegate=self

        }

        

        let maxSeesawAngle=M_PI / 12

        

        var currentSeesawAngle = 0.0

        

        var animate:Bool = false{

            

        didSet(oldAnimate){

            if animate != oldAnimate && animate {

                if currentSeesawAngle == 0  {

                    

                    //@Bailey

                    //设置捕捉动态记录和显示的参数

                    XCPCaptureValue("Left Seesaw Position",0 )

                     animateSeesawToAngle(maxSeesawAngle,duration: 0.75)

                }

                else

                {

                   animateSeesawToAngle(currentSeesawAngle * -1)

                }

            }

        }

        }

        

        func animateSeesawToAngle(angle:CGFloat,duration:CFTimeInterval = 1.5 )-> CAAnimation{

            let angleAnimation = CABasicAnimation(keyPath:"transform")

            angleAnimation.fromValue=NSValue(CATransform3D:seesawLayer.transform)

            

            angleAnimation.toValue=NSValue(CATransform3D:CATransform3DMakeRotation(angle, 0.0, 0.0, 1.0))

            

            angleAnimation.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)

            

            angleAnimation.duration = duration

            angleAnimation.delegate=self

            seesawLayer.addAnimation(

                angleAnimation, forKey: "transform")

            

            seesawLayer.transform=CATransform3DMakeRotation(angle,0.0, 0.0, 1.0)

            currentSeesawAngle=angle

            return angleAnimation

            

        }

        

        override func animationDidStop(_:CAAnimation!,finished:Bool){

            if finished && animate {

                

                //@Bailey

                //设置捕捉动态记录和显示的参数

                XCPCaptureValue("Left Seesaw Position",-currentSeesawAngle )

                animateSeesawToAngle(currentSeesawAngle * -1)

            }

        }

    }

    extension NSColor {

        class func playgroundIconFillColoer()->NSColor{

            return NSColor(red:12/255,green:65/255,blue:135/255,alpha:1.0)

        }

        class func playgroundIconStrokeColor()->NSColor{

            return NSColor(red:9/255,green:44/255,blue:91/255,alpha:1.0)

        }

    }

    func CGPathFromNSBezierPath(nsPath:NSBezierPath)->CGPath! {

        if nsPath.elementCount==0{

            return nil

        }

        

        let path=CGPathCreateMutable()

        var didClosePath=false

        for i in 0..nsPath.elementCount{

            var points=NSPoint[](count:3,repeatedValue:NSZeroPoint)

            

            switch nsPath.elementAtIndex(i, associatedPoints: &points){

            case .MoveToBezierPathElement:

                CGPathMoveToPoint(path,nil,points[0].x,points[0].y)

                

            case .LineToBezierPathElement:

                CGPathAddLineToPoint(path, nil, points[0].x, points[0].y)

                

            case .CurveToBezierPathElement:

                CGPathAddCurveToPoint(path,nil, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y)

            case .ClosePathBezierPathElement:

                CGPathCloseSubpath(path)

                didClosePath=true

             }

        }

        if !didClosePath{

            CGPathCloseSubpath(path)

        }

        return CGPathCreateCopy(path)

    }

    let view=PlaygroundIconView()

    view.animate=true

    //@Bailey

    //显示游乐场跷跷板动态图标以及时间轴用于程序计算回溯

    XCPShowView("20140605",view)

    view

     

    //修正程序以适应新swift的语法 ,在 xcode 6.1 下运行

    import Cocoa

    import Foundation

    import QuartzCore

    import XCPlayground

    import SpriteKit

     class PlaygroundIconView:NSView {

        let backgroundLayer=CAShapeLayer()

        let seesawBaseLayer=CAShapeLayer()

        let seesawLayer=CAShapeLayer()

        required init?(coder: NSCoder){

            super.init(frame:NSRect(x:0,y:0,568,height:568))

            backgroundLayer.frame=self.bounds

            seesawBaseLayer.frame=NSRect(x:254,y:124,60,height:111)

            seesawLayer.frame=NSRect(x:40,y:197, 488,height:30)

            setUpBackgroundLayer()

            setUpSeesawBaseLayer()

            setUpSeesawLayer()

            self.wantsLayer=true

            self.layer?.addSublayer(backgroundLayer)

            self.layer?.addSublayer(seesawBaseLayer)

            self.layer?.addSublayer(seesawLayer)

        }

        

        func setUpBackgroundLayer(){

            let lineWidth=9.0

            let backgroundPath=NSBezierPath(roundedRect:NSInsetRect(bounds, CGFloat(lineWidth/2), CGFloat(lineWidth/2)),xRadius:35.0,yRadius:35.0)

            backgroundPath.lineWidth=CGFloat(lineWidth)

            backgroundLayer.strokeColor=NSColor.playgroundIconStrokeColor().CGColor

            backgroundLayer.fillColor=NSColor.playgroundIconFillColoer().CGColor

            backgroundLayer.lineWidth=CGFloat(lineWidth)

            backgroundLayer.path=CGPathFromNSBezierPath(backgroundPath)

        }

        

        func setUpSeesawBaseLayer(){

            let seesawBasePath=NSBezierPath()

            let rectHeight:Int=50;

            seesawBasePath.moveToPoint(NSPoint(x:0,y:rectHeight))

            seesawBasePath.lineToPoint(NSPoint(x:seesawBaseLayer.bounds.width/2,y:seesawBaseLayer.bounds.height))

            seesawBasePath.lineToPoint(NSPoint(x:seesawBaseLayer.bounds.width,y:50))

            seesawBaseLayer.fillColor=NSColor.whiteColor().CGColor

            seesawBaseLayer.path=CGPathFromNSBezierPath(seesawBasePath)

        }

        

        func setUpSeesawLayer(){

            let createChildLayer:()->CAShapeLayer={

            let childLayer=CAShapeLayer()

            let headPath=NSBezierPath(ovalInRect:NSRect(x:60,y:150,49,height:49))

            let bodyPath=NSBezierPath()

            bodyPath.moveToPoint(NSPoint(x:58,y:155))

            bodyPath.lineToPoint(NSPoint(x:88,y:140))

            bodyPath.lineToPoint(NSPoint(x:126,y:100))

            bodyPath.lineToPoint(NSPoint(x:120,y:90))

            bodyPath.lineToPoint(NSPoint(x:125,y:71))

            bodyPath.lineToPoint(NSPoint(x:113,y:71))

            bodyPath.lineToPoint(NSPoint(x:112,y:94))

            bodyPath.lineToPoint(NSPoint(x:83,y:113))

            bodyPath.lineToPoint(NSPoint(x:68,y:94))

            bodyPath.lineToPoint(NSPoint(x:97,y:70))

            bodyPath.lineToPoint(NSPoint(x:122,y:12))

            bodyPath.lineToPoint(NSPoint(x:98,y:0))

            bodyPath.lineToPoint(NSPoint(x:64,y:41))

            bodyPath.lineToPoint(NSPoint(x:7,y:71))

            bodyPath.lineToPoint(NSPoint(x:0,y:94))

            bodyPath.moveToPoint(NSPoint(x:58,y:155))

            

            let childPath=NSBezierPath()

            childPath.appendBezierPath(headPath)

            childPath.appendBezierPath(bodyPath)

            childLayer.fillColor=NSColor.whiteColor().CGColor

            childLayer.path=CGPathFromNSBezierPath(childPath)

            

            return childLayer

            }

            

            let leftChildLayer = createChildLayer()

            let rightChildLayer = createChildLayer()

            rightChildLayer.transform=CATransform3DMakeRotation(CGFloat(M_PI),0.0,0.0,1.0)

            rightChildLayer.geometryFlipped=true

            let benchLayer = CALayer()

            benchLayer.frame=NSRect(x:0,y:41,self.seesawLayer.bounds.width,height:30)

            benchLayer.backgroundColor=NSColor.whiteColor().CGColor

            leftChildLayer.frame=NSRect(x:25,y:0,126,height:200)

            rightChildLayer.frame=NSRect(x:488-(126+25),y:0,126,height:200)

            seesawLayer.addSublayer(leftChildLayer)

            seesawLayer.addSublayer(rightChildLayer)

            seesawLayer.addSublayer(benchLayer)

            seesawLayer.delegate=self

        }

        let maxSeesawAngle=M_PI / 12

        var currentSeesawAngle = 0.0

        var animate:Bool = false{

        

        didSet(oldAnimate){

                if animate != oldAnimate && animate {

                    if currentSeesawAngle == 0  {

                        //@Bailey

                        //设置捕捉动态记录和显示的参数

                        XCPCaptureValue("Left Seesaw Position",0 )

                        animateSeesawToAngle(CGFloat(maxSeesawAngle),duration: 0.75)

                    }

                    else

                    {

                        animateSeesawToAngle(CGFloat(currentSeesawAngle * -1))

                    }

                }

            }

        }

        

        func animateSeesawToAngle(angle:CGFloat,duration:CFTimeInterval = 1.5 )-> CAAnimation{

            let angleAnimation = CABasicAnimation(keyPath:"transform")

            angleAnimation.fromValue=NSValue(CATransform3D:seesawLayer.transform)

            angleAnimation.toValue=NSValue(CATransform3D:CATransform3DMakeRotation(angle, 0.0, 0.0, 1.0))

            angleAnimation.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)

            angleAnimation.duration = duration

            angleAnimation.delegate=self

            seesawLayer.addAnimation(

                angleAnimation, forKey: "transform")

            seesawLayer.transform=CATransform3DMakeRotation(angle,0.0, 0.0, 1.0)

            currentSeesawAngle=Double(angle)  //tag

            return angleAnimation

        }

        

        override func animationDidStop(_:CAAnimation!,finished:Bool){

            if finished && animate {

                //@Bailey

                //设置捕捉动态记录和显示的参数

                XCPCaptureValue("Left Seesaw Position",-currentSeesawAngle )

                animateSeesawToAngle( CGFloat(currentSeesawAngle * -1)  )

            }

        }

     }

     extension NSColor {

        class func playgroundIconFillColoer()->NSColor{

            return NSColor(red:12/255,green:65/255,blue:135/255,alpha:1.0)

        }

        

        class func playgroundIconStrokeColor()->NSColor{

            return NSColor(red:9/255,green:44/255,blue:91/255,alpha:1.0)

        }

     }

     func CGPathFromNSBezierPath(nsPath:NSBezierPath)->CGPath! {

        if nsPath.elementCount==0{

            return nil

        }

        let path=CGPathCreateMutable()

        var didClosePath=false

        for i in 0..<nsPath.elementCount{

            var points=[NSPoint](count:3,repeatedValue:NSZeroPoint)

            switch nsPath.elementAtIndex(i, associatedPoints: &points){

            case .MoveToBezierPathElement:

                CGPathMoveToPoint(path,nil,points[0].x,points[0].y)

            case .LineToBezierPathElement:

                CGPathAddLineToPoint(path, nil, points[0].x, points[0].y)

            case .CurveToBezierPathElement:

                CGPathAddCurveToPoint(path,nil, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y)

            case .ClosePathBezierPathElement:

                CGPathCloseSubpath(path)

                didClosePath=true

            }

        }

        if !didClosePath{

            CGPathCloseSubpath(path)

        }

        return CGPathCreateCopy(path)

     }

     let view=PlaygroundIconView(coder: NSCoder())

     view?.animate=true

     //@Bailey

     //显示游乐场跷跷板动态图标以及时间轴用于程序计算回溯

     XCPShowView("20140605",view!)

     view

     

  • 相关阅读:
    Grunt构建工具插件篇——之less工具
    Grunt构建工具能做哪些事?
    Grunt-几个常用的任务配置,加载,执行的写法
    单元测试任务包括哪些?
    单元测试的概念
    分享Grunt.js配置: watch + liveReload 实时监测文件变化自动刷新浏览器
    如何使用Grunt(好文)
    grunt安装详解及失败处理
    利用 Grunt (几乎)无痛地做前端开发 (一)之单元测试
    Grunt实现自动化单元测试
  • 原文地址:https://www.cnblogs.com/bailey/p/3777071.html
Copyright © 2011-2022 走看看