Холст для рисования

Рисование фигур внутри UIView производится через задание в подклассе логики методу drawRect. Каждый раз создавать нового наследника непрактично, кроме того, такой способ не отличается гибкостью в плане управления процессом рисования.

Полезно иметь класс-холст. Для себя я разработал CanvasView. С ним рисование сводится к добавлению нужных путей в массив. CanvasPath — банальный наследник UIBezierPath с цветами обводки и заливки.

import UIKit

/**
The `CanvasPath` class extends UIBezierPath by adding stroke and fill colors. 
Used in `CanvasView` class.
*/
class CanvasPath: UIBezierPath {

    // MARK: - Properties
    /**
    The stroke color.
    */
    var strokeColor: UIColor?

    /**
    The fill color.
    */
    var fillColor: UIColor?
}

/**
The `CanvasView` class makes it easy to draw the shapes inside.
*/
class CanvasView: UIView {

    // MARK: - Properties
    /**
    The paths that are be drawn.
    */
    var paths = [CanvasPath]() {
        didSet {
            // Redraw paths
            setNeedsDisplay()
        }
    }

    // MARK: - Initialization
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    private func setup() {
        // Set false for default transparent background color.
        opaque = false
    }

    // MARK: - Drawing
    override func drawRect(rect: CGRect) {
        for path in paths {
            if path.strokeColor != nil {
                path.strokeColor!.setStroke()
                path.stroke()
            }
            
            if path.fillColor != nil {
                path.fillColor!.setFill()
                path.fill()
            }
        }
    }
}

Пример использования.

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let canvas = CanvasView(frame: CGRect(x: 0, y: 0, width: 400, height: 300))

        let borders = CanvasPath()
        borders.strokeColor = UIColor(white: 0.9, alpha: 1)
        borders.moveToPoint(CGPoint(x: 20, y: 50))
        borders.addLineToPoint(CGPoint(x: 350, y: 50))
        borders.addLineToPoint(CGPoint(x: 350, y: 275))
        borders.addLineToPoint(CGPoint(x: 20, y: 275))
        borders.addLineToPoint(CGPoint(x: 20, y: 50))

        let white = CanvasPath(rect: CGRect(x: 20, y: 50, width: 330, height: 75))
        white.fillColor = UIColor.whiteColor()

        let blue = CanvasPath(rect: CGRect(x: 20, y: 125, width: 330, height: 75))
        blue.fillColor = UIColor(red: 0, green: 0.224, blue: 0.651, alpha: 1)

        let red = CanvasPath(rect: CGRect(x: 20, y: 200, width: 330, height: 75))
        red.fillColor = UIColor(red: 0.835, green: 0.169, blue: 0.118, alpha: 1)

        canvas.paths += [borders, white, blue, red]

        view.addSubview(canvas)
    }
}

Скачать CanvasView.zip