Alessandro
Alessandro

Reputation: 199

MouseMoved function is never called

I'm trying to override mouseMoved function in NSViewController.

import Cocoa

class MainViewController: NSViewController {

override var acceptsFirstResponder: Bool {get {return true} }

@IBOutlet var background: RandomNumberBackground!
override func viewDidLoad() {
    super.viewDidLoad() 
}

override func awakeFromNib() {
    NSTimer.scheduledTimerWithTimeInterval(0.04, target: background, selector: "updateNumbers", userInfo: nil, repeats: true)
}

@IBAction func btnLevelClicked(sender: AnyObject) {
      self.presentViewControllerAsSheet(LevelScrollController())
}

override func mouseMoved(theEvent: NSEvent) {
    Swift.print("MOVED!")
}

}

I've overrided acceptsFirstResponder but mouseMoved is never called. Why? Where I go wrong?

Upvotes: 0

Views: 2796

Answers (5)

Moose
Moose

Reputation: 2737

This is the code I add when I need to track mouse moves in a view. It is longer than previous answers, but this is what it takes to be done properly :)

class MyView: NSView {
    
    var trackingArea: NSTrackingArea?

    // MARK: - Tracking area management

    /// Will install tracking area on the view if a window is set
    override func viewDidMoveToSuperview() {
        super.viewDidMoveToSuperview()
        installTrackingArea()
    }
    
    /// Install tracking area if window is set, remove previous one if needed.
    func installTrackingArea() {
        guard let window = window else { return }
        window.acceptsMouseMovedEvents = true
        if trackingArea != nil { removeTrackingArea(trackingArea!) }
        let trackingOptions = [.activeAlways, .mouseEnteredAndExited, .mouseMoved]
        trackingArea = NSTrackingArea(rect: bounds, 
                                      options: trackingOptions, 
                                      owner: self, userInfo: nil)
        self.addTrackingArea(trackingArea!)
    }
    
    /// Called when layout is modified
    override func updateTrackingAreas() {
        super.updateTrackingAreas()
        installTrackingArea()
    }

    //MARK: - Mouse Events handling

    override func mouseExited(with event: NSEvent) {
        print("Good bye mouse")
    }
    
    override func mouseEntered(with event: NSEvent) {
        let point = self.convert(event.locationInWindow, from: nil)
        print("Hello mouse, welcome at \(point)")
    }

    override func mouseMoved(with event: NSEvent) {
        let point = self.convert(event.locationInWindow, from: nil)
        print("Mouse moved \(point)")
    }
}

Upvotes: 2

Adamb
Adamb

Reputation: 59

No need to set anything on the window.

A tracking area is the proper way to handle this.

Just add this in the VC's vieWDidLoad() method.

let ta = NSTrackingArea(rect: CGRect.zero, options: [.activeAlways, .inVisibleRect, .mouseMoved], owner: self, userInfo: nil)
self.view.addTrackingArea(ta)

Upvotes: 2

ackers
ackers

Reputation: 63

In swift 3 you can put this in your viewDidLoad()

self.view!.window?.acceptsMouseMovedEvents = true;

Upvotes: 0

alessandro308
alessandro308

Reputation: 2162

You need to set acceptsMouseMovedEvents in the windows property.

Add the following code to applicationDidFinishLaunching

func applicationDidFinishLaunching(aNotification: NSNotification) {
    window.acceptsMouseMovedEvents = true
}

Upvotes: 2

Related Questions