Swift 3: Drawing a rectangle
Asked Answered
C

4

15

I'm 3 days new to swift, and I'm trying to figure out how to draw a rectangle. I'm too new to the language to know the classes to extend and the methods to override, and I've looked around for sample code, but nothing seems to work (which I'm attributing to my use of swift 3).

What I'm trying now is:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()


        let k = Draw(frame: CGRect(
            origin: CGPoint(x: 50, y: 50),
            size: CGSize(width: 100, height: 100)))

        k.draw(CGRect(
            origin: CGPoint(x: 50, y: 50),
            size: CGSize(width: 100, height: 100)));
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
class Draw: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        let h = rect.height
        let w = rect.width
        var color:UIColor = UIColor.yellow()

        var drect = CGRect(x: (w * 0.25),y: (h * 0.25),width: (w * 0.5),height: (h * 0.5))
        var bpath:UIBezierPath = UIBezierPath(rect: drect)

        color.set()
        bpath.stroke()

        print("it ran")

        NSLog("drawRect has updated the view")

    }

}

And that's not doing anything. Help.

Corelative answered 26/6, 2016 at 20:35 Comment(2)
If you're just starting out, asking broad questions like this on Stack Overflow is not the place you need to be. You should find a good book or a series of online tutorials. Have a look at Good resources for learning ObjC; it includes references for iOS, and most of the material will have been updated for Swift at this point. Good luck!Lan
1. Never call draw yourself. 2. Just call view.addSubview(k) to add the view to your view hierarchy, and the OS will call draw method for you when it needs.Acceptation
Q
17

In order to see the view, you need to create one and give it frame so that it knows how big to make it.

If you put your code in a Playground, and then add this line:

let d = Draw(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

You'll be able to click on the Quick View on the right, and then you'll see the view.

Yellow square in a playground


You can also add the view as a subview of view in your ViewController and then you'll see it on the iPhone:

override func viewDidLoad() {
    super.viewDidLoad()

    let k = Draw(frame: CGRect(
        origin: CGPoint(x: 50, y: 50),
        size: CGSize(width: 100, height: 100)))

    // Add the view to the view hierarchy so that it shows up on screen
    self.view.addSubview(k)
}

Note that you never call draw(_:) directly. It is called for you by Cocoa Touch to display the view.

Yellow square on iPhoneSE

Quiche answered 26/6, 2016 at 20:46 Comment(1)
I get error: Cannot find 'Draw' in scopeSindhi
A
10

Create a class, I put it in a separate Swift 3 file.

//
//  Plot_Demo.swift
//
//  Storyboard is not good in creating self adapting UI
//  Plot_Demo creates the drawing programatically.

import Foundation
import UIKit

public class Plot_Demo: UIView
{
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public override func draw(_ frame: CGRect) {
        let h = frame.height
        let w = frame.width
        let color:UIColor = UIColor.yellow

        let drect = CGRect(x: (w * 0.25), y: (h * 0.25), width: (w * 0.5), height: (h * 0.5))
        let bpath:UIBezierPath = UIBezierPath(rect: drect)

        color.set()
        bpath.stroke()

        print("it ran")
        NSLog("drawRect has updated the view")
    }
}

Example of use in an UIViewController object:

override func viewDidLoad() {
    super.viewDidLoad()

    // Instantiate a new Plot_Demo object (inherits and has all properties of UIView)
    let k = Plot_Demo(frame: CGRect(x: 75, y: 75, width: 150, height: 150))

    // Put the rectangle in the canvas in this new object
    k.draw(CGRect(x: 50, y: 50, width: 100, height: 100))

    // view: UIView was created earlier using StoryBoard
    // Display the contents (our rectangle) by attaching it
    self.view.addSubview(k)
}

Run in an iPhone simulator and on an iPhone:

enter image description here

Used XCode Version 8.0 (8A218a), Swift 3, target iOS 10.0

Amathiste answered 24/11, 2016 at 16:52 Comment(1)
From draw(_:) documentation: – You should never call this method directly yourself. To invalidate part of your view, and thus cause that portion to be redrawn, call the setNeedsDisplay() or setNeedsDisplay(_:) method instead.Lemonade
L
3

This is another way of drawing Rectangle,

Step 1: Get rectangle path for given points

(Note: arrPathPoints must be 4 in count to draw rectangle),

func getPathPayer(arrPathPoints:[CGPoint]) throws -> CAShapeLayer {
        enum PathError : Error{
            case moreThan2PointsNeeded
        }

        guard arrPathPoints.count > 2 else {
            throw PathError.moreThan2PointsNeeded
        }

        let lineColor = UIColor.blue
        let lineWidth: CGFloat = 2
        let path = UIBezierPath()
        let pathLayer = CAShapeLayer()

        for (index,pathPoint) in arrPathPoints.enumerated() {
            switch index {
            //First point
            case 0:
                path.move(to: pathPoint)

            //Last point
            case arrPathPoints.count - 1:
                path.addLine(to: pathPoint)
                path.close()

            //Middle Points
            default:
                path.addLine(to: pathPoint)
            }
        }

        pathLayer.path = path.cgPath
        pathLayer.strokeColor = lineColor.cgColor
        pathLayer.lineWidth = lineWidth
        pathLayer.fillColor = UIColor.clear.cgColor

        return pathLayer
    }

Step 2: Usage, Call method like this,

override func viewDidLoad() {
        super.viewDidLoad()

        do {
            let rectangleLayer = try getPathPayer(arrPathPoints: [
                CGPoint(x: 110, y: 110),    //Top-Left
                CGPoint(x: 130, y: 110),    //Top-Right
                CGPoint(x: 130, y: 130),    //Bottom-Right
                CGPoint(x: 110, y: 130)])   //Bottom-Left
            view.layer.addSublayer(rectangleLayer)
        } catch {
            debugPrint(error)
        }
    }
Lello answered 6/9, 2017 at 12:43 Comment(0)
L
3

My version of how to draw a rectangle using Swift 5.

First create a class to do the drawing. It uses CoreGraphics to do the drawing, rather than UIKit.

import UIKit

class DrawRectangle: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

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

    override func draw(_ rect: CGRect) {

        guard let context = UIGraphicsGetCurrentContext() else {
            print("could not get graphics context")
            return
        }

        context.setStrokeColor(UIColor.yellow.cgColor)
        context.setLineWidth(2)
        context.stroke(rect.insetBy(dx: 10, dy: 10))
    }
}

Then put this in your ViewController's viewDidLoad()

    let myView = DrawRectangle(frame: CGRect(x: 50, y: 50, width: 100, height: 100))

    self.view.addSubview(myView)
Len answered 21/3, 2020 at 16:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.