Reputation: 199
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
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
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
Reputation: 63
In swift 3 you can put this in your viewDidLoad()
self.view!.window?.acceptsMouseMovedEvents = true;
Upvotes: 0
Reputation: 2993
You need to set the acceptsMouseMovedEvents
property on the window the view belongs to. See
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/index.html#//apple_ref/occ/instp/NSWindow/acceptsMouseMovedEvents
Upvotes: 0
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