1

I'm trying to draw a line in my MacOS app but I do not see the line. What can be a problem?

My code looks like:

func addLine() {
    let path = NSBezierPath()
    path.move(to: NSPoint(x: 100.0, y: 100))
    path.line(to: NSPoint(x: 200.0, y: 200.0))
    NSColor.green.setFill()
    NSColor.green.setStroke()
    path.close()
    path.stroke()
}

And I call it in:

override func viewDidLoad() {
    super.viewDidLoad()

    addLine()
}

Am I doing something wrong? I just do not see anything in my window.

J. Doe
  • 521
  • 4
  • 15

1 Answers1

2

Have you created your own subclass of a NSView?

If I create a new view and add your code like so:

import Cocoa

class MyView: NSView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        addLine()
    }

    func addLine() {
        let path = NSBezierPath()
        path.move(to: NSPoint(x: 100.0, y: 100))
        path.line(to: NSPoint(x: 200.0, y: 200.0))
        NSColor.green.setFill()
        NSColor.green.setStroke()
        path.close()
        path.stroke()
    }
}

And I then - in a storyboard - drag a "Custom View" to the canvas, change the type of the view to be MyView like sostoryboard setup

Then I see this when running the app:

tada

If you prefer to add the view in code, you can do something like this:

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let myView = MyView()
        myView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(myView)
        myView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        myView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        myView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        myView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
    }
}

So, your code seems to work, I'm just not sure how you are trying to use it.

Hope that gives you something to continue with.

pbodsk
  • 6,787
  • 3
  • 21
  • 51
  • is there a way of doing that without creating NSView class? Just in my NSViewController – J. Doe Aug 05 '18 at 14:06
  • @J.Doe You probably could, I tried some things...without luck though. I think the problem is that `NSViewControllers` and "low level drawing" as you're trying to do here works on two different levels in the tech stack if that makes sense. `NSViewControllers` are for quickly laying out your view and populate it (through `@IBOutlets`), handle user input (`@IBAction`) and so on. Whereas drawing is more "low level" and requires you to work closer to the metal. If you look long enough, you could probably find someone who knows how to combine those two "worlds", but I don't know how, sorry :( – pbodsk Aug 05 '18 at 14:22