How to procedurally draw rectangle / lines in swift using CGContext

I’ve been trawling the internet for days trying to find the simplest code examples on how to draw a rectangle or lines procedurally in Swift. I have seen how to do it by overriding the DrawRect command. I believe you can create a CGContext and then drawing into an image, but I’d love to see some simple code examples. Or is this a terrible approach? Thanks.

class MenuController: UIViewController 
{

    override func viewDidLoad() 
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor.blackColor()

        var logoFrame = CGRectMake(0,0,118,40)
        var imageView = UIImageView(frame: logoFrame)
        imageView.image = UIImage(named:"Logo")
        self.view.addSubview(imageView)

        //need to draw a rectangle here
    }
}

  • Draw a simple circle uiimage
  • UIGraphicsGetImageFromCurrentImageContext memory leak with previews
  • How to draw a UILabel with a different blend mode in draw(_ rect: CGRect) in Swift
  • Drawing a dashed line with CGContextSetLineDash
  • objective c renderInContext crash on background thread
  • drawInRect: losing Quality of Image resolution
  • 3 Solutions Collect From Internet About “How to procedurally draw rectangle / lines in swift using CGContext”

    Here’s an example that creates a custom UIImage containing a transparent background and a red rectangle with lines crossing diagonally through it.

    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad();
    
            let imageSize = CGSize(width: 200, height: 200)
            let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
            self.view.addSubview(imageView)
            let image = drawCustomImage(imageSize)
            imageView.image = image
        }
    }
    
    func drawCustomImage(size: CGSize) -> UIImage {
        // Setup our context
        let bounds = CGRect(origin: CGPoint.zeroPoint, size: size)
        let opaque = false
        let scale: CGFloat = 0
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        let context = UIGraphicsGetCurrentContext()
    
        // Setup complete, do drawing here
        CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
        CGContextSetLineWidth(context, 2.0)
    
        CGContextStrokeRect(context, bounds)
    
        CGContextBeginPath(context)
        CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds))
        CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))
        CGContextMoveToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds))
        CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMaxY(bounds))
        CGContextStrokePath(context)
    
        // Drawing complete, retrieve the finished image and cleanup
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    

    An updated answer using Swift 3.0

    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad();
    
            let imageSize = CGSize(width: 200, height: 200)
            let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
            self.view.addSubview(imageView)
            let image = drawCustomImage(size: imageSize)
            imageView.image = image
        }
    }
    
    func drawCustomImage(size: CGSize) -> UIImage? {
        // Setup our context
        let bounds = CGRect(origin: CGPoint.zero, size: size)
        let opaque = false
        let scale: CGFloat = 0
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
    
        // Setup complete, do drawing here
        context.setStrokeColor(UIColor.red.cgColor)
        context.setLineWidth(5.0)
    
        // Would draw a border around the rectangle
        // context.stroke(bounds)
    
        context.beginPath()
        context.move(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        context.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
        context.strokePath()
    
        // Drawing complete, retrieve the finished image and cleanup
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    let imageSize = CGSize(width: 200, height: 200)
    let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
    let image = drawCustomImage(size: imageSize)
    imageView.image = image
    

    I used the accepted answer to draw lines in a Tic Tac Toe game when one of the players won. Thanks, good to know that it worked. Unfortunately, I ran into some problems getting it to work on different sizes of iPhones and iPads simultaneously. That’s probably something that should have been addressed. Basically what I’m saying is that it might not actually be worth the trouble of all that code, depending on your case.

    My alternate solution is to simply make customized, better looking line in Photoshop and then load it with UIImageView. For me this was MUCH simpler, runs better, and looks better. Obviously it really depends on what you need it for.

    Steps:

    1: Download or create an image (preferably saved as .PNG)

    2: Drag it into your project

    3: Drag a UIImage View into your storyboard

    4: Click on the Image View and select the image in the attributes inspector

    5: Ctrl click and drag the Image View to your .swift file to declare an Outlet

    6: Set the autolayout constraints so it works on ALL devices EASILY

    Animating, rotating, and transforming image views on and off the screen is also arguably easier

    To change the image:

    yourImageViewOutletName.image = UIImage(named: "ImageNameHere")