Search code examples
iosxcodeswiftcore-graphicsswift-playground

Rotation And Gradient in CoreGraphics and context


I'm definitely missing some parts of Core Graphics context and cannot clear things out by myself. Here is my code in Xcode Playground

import UIKit
class MyView08 : UIView {

    override func drawRect(rect: CGRect) {
        let cornerRaduis : CGFloat = 20
        let pathRect = CGRectInset(self.bounds, 20, 20)
        let rectanglePath = UIBezierPath(roundedRect: pathRect, cornerRadius: cornerRaduis)
        var context = UIGraphicsGetCurrentContext()
        CGContextSaveGState(context)
        rotate(rectanglePath, context: context)
        CGContextRestoreGState(context)

        context = UIGraphicsGetCurrentContext()
        CGContextSaveGState(context)
    //  drawGrad(rectanglePath, context: context)
        CGContextRestoreGState(context)
    }

    func rotate(rectanglePath : UIBezierPath, context : CGContext) {
        let rotation = CGAffineTransformMakeRotation(CGFloat(M_PI) / 4.0)
        CGContextConcatCTM(context, rotation)
        UIColor.greenColor().setFill()
        rectanglePath.fill()

    }

    func drawGrad (rectanglePath : UIBezierPath, context : CGContext) {
        let startColor = UIColor.redColor()
        let endColor = UIColor.greenColor()
        let gradientColors : CFArray = [startColor.CGColor, endColor.CGColor]
        let gradientLocations : [CGFloat] = [0.0, 1.0]
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let gradient = CGGradientCreateWithColors(colorSpace, gradientColors, gradientLocations)
        let topPoint = CGPointMake(self.bounds.size.width / 2, 20)
        let bottomPoint = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height - 20)

        rectanglePath.addClip()
        CGContextDrawLinearGradient(context, gradient, bottomPoint, topPoint, 0)
    }
}

let myViewRect = CGRect(x: 0, y: 0, width: 300, height: 300)
let myView = MyView08(frame: myViewRect)

If i uncomment this line

drawGrad(rectanglePath, context: context)

Everything is going bad, Xcode trying to execute code almost 2 thousands times and after that it fails. I'm trying to rotate rectangle and draw a gradient.


Solution

  • You are experiencing an infinite recursion. I don't know why, but it has to do with your testing procedure. The problem lies in how you are testing - not in your code. Don't test this kind of code in a playground. Playgrounds are not reality.

    (I could generalize and say, don't use playgrounds ever. They are the work of the devil. But I'm not going to. Ooops, did I say that out loud?)

    Anyway, I copied and pasted your code into a fresh app project (and I uncommented the drawGrad line), and it ran just fine with no recursion issues of the kind you describe.

    Note that you will need to put your view into the interface in order for it to do anything. I added this line in order to do that:

        self.view.addSubview(myView)
    

    Apart from that, my code is identical to yours, and there's no problem.