QuartzDemo/QuartzPatternView.swift

/*
 Copyright (C) 2017 Apple Inc. All Rights Reserved.
 See LICENSE.txt for this sample’s licensing information
 
 Abstract:
 Demonstrates using Quartz for drawing patterns.
 */
 
 
 
 
 
import UIKit
 
 
 
class QuartzPatternView: QuartzView {
 
 
 
    var coloredPatternColor: CGColor = {
 
        // Colored Pattern setup.  CGPatterns have callbacks to do the drawing.
        var coloredPatternCallbacks =
            CGPatternCallbacks(version: 0,
                               drawPattern: { (info: UnsafeMutableRawPointer?, context: CGContext) -> Swift.Void in
                                // Dark Blue
                                context.setFillColor(red: 29.0 / 255.0, green: 156.0 / 255.0, blue: 215.0 / 255.0, alpha: 1.00)
                                context.fill(CGRect(x: 0.0, y: 0.0, width: 8.0, height: 8.0))
                                context.fill(CGRect(x: 8.0, y: 8.0, width: 8.0, height: 8.0))
                                // Light Blue
                                context.setFillColor(red: 204.0 / 255.0, green: 224.0 / 255.0, blue: 244.0 / 255.0, alpha: 1.00)
                                context.fill(CGRect(x: 8.0, y: 0.0, width: 8.0, height: 8.0))
                                context.fill(CGRect(x: 0.0, y: 8.0, width: 8.0, height: 8.0)) },
                               releaseInfo: nil)
 
        // First we need to create a CGPatternRef that specifies the qualities of our pattern.
        let coloredPattern = CGPattern(info: nil,
                                       bounds: CGRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0),
                                       matrix: CGAffineTransform.identity,
                                       xStep: 16.0,
                                       yStep: 16.0,
                                       tiling: .noDistortion,
                                       isColored: true,
                                       callbacks: &coloredPatternCallbacks)!
        // To draw a pattern, you need a pattern colorspace.
        // Since this is an colored pattern, the parent colorspace is NULL, indicating that it only has an alpha value.
        var coloredPatternColorSpace = CGColorSpace(patternBaseSpace: nil)!
        var alpha: CGFloat = 1.0
 
        // Since this pattern is colored, we'll create a CGColorRef for it to make drawing it easier and more efficient.
        // From here on, the colored pattern is referenced entirely via the associated CGColorRef rather than the
        // originally created CGPatternRef.
        return CGColor(patternSpace: coloredPatternColorSpace, pattern: coloredPattern, components: &alpha)!
    }()
 
 
 
    var uncoloredPattern: CGPattern = {
        var uncoloredPatternCallbacks =
            CGPatternCallbacks(version: 0,
                               drawPattern: {(info: UnsafeMutableRawPointer?, context: CGContext) -> Swift.Void in
                                // Dark Blue
                                context.fill(CGRect(x: 0.0, y: 0.0, width: 8.0, height: 8.0))
                                context.fill(CGRect(x: 8.0, y: 8.0, width: 8.0, height: 8.0)) },
                               releaseInfo: nil)
 
        // As above, we create a CGPatternRef that specifies the qualities of our pattern
        return CGPattern(info: nil,
                         bounds: CGRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0),
                         matrix: CGAffineTransform.identity,
                         xStep: 16.0, yStep: 16.0,
                         tiling: .noDistortion,
                         isColored: false,
                         callbacks: &uncoloredPatternCallbacks)!
    }()
 
 
 
    var uncoloredPatternColorSpace: CGColorSpace = {
        var deviceRGB: CGColorSpace = CGColorSpaceCreateDeviceRGB()
        return CGColorSpace(patternBaseSpace: deviceRGB)!
    }()
 
 
 
    override func drawInContext(_ context: CGContext) {
 
        centerDrawing(inContext: context,  drawingExtent: CGRect(x:0.0, y:0.0, width:220.0, height:330.0))
 
        // Draw the colored pattern. Since we have a CGColorRef for this pattern, we just set
        // that color current and draw.
        context.setFillColor(coloredPatternColor)
        context.fill(CGRect(x: 10.0, y: 10.0, width: 90.0, height: 90.0))
 
        // You can also stroke with a pattern.
        context.setStrokeColor(coloredPatternColor)
        context.stroke(CGRect(x: 120.0, y: 10.0, width: 90.0, height: 90.0), width: 8)
 
        // Since we aren't encapsulating our pattern in a CGColorRef for the uncolored pattern case, setup requires two steps.
        // First you have to set the context's current colorspace (fill or stroke) to a pattern colorspace,
        // indicating to Quartz that you want to draw a pattern.
        context.setFillColorSpace(uncoloredPatternColorSpace)
        // Next you set the pattern and the color that you want the pattern to draw with.
        let color1: [CGFloat] = [1.0, 0.0, 0.0, 1.0]
        context.setFillPattern(uncoloredPattern, colorComponents: color1)
        // And finally you draw!
        context.fill(CGRect(x: 10.0, y: 120.0, width: 90.0, height: 90.0))
 
        // As long as the current colorspace is a pattern colorspace, you are free to change the pattern or pattern color
        let color2: [CGFloat] = [0.0, 1.0, 0.0, 1.0]
        context.setFillPattern(uncoloredPattern, colorComponents: color2)
        context.fill(CGRect(x: 10.0, y: 230.0, width: 90.0, height: 90.0))
 
        // And of course, just like the colored case, you can stroke with a pattern as well.
        context.setStrokeColorSpace(uncoloredPatternColorSpace)
        context.setStrokePattern(uncoloredPattern, colorComponents: color1)
        context.stroke(CGRect(x: 120.0, y: 120.0, width: 90.0, height: 90.0), width: 8)
        
    }
 
}