简体   繁体   中英

acceptsFirstMouse … doesn't work (Swift 4.0, NSView)

When you do an 'override func acceptsFirstMouse' that returns true, the View should act as a first responder, even if it isn't in focus, right? Well it doesn't work. Wrote a little demo program: When you MouseDown on the background, it changes color. But: when you open a new window and the old window gets out of focus, this doesn't happen anymore. You first have to bring the old window into focus again.

Does anybody know how to make this work?

By the way, buttons always accept first mouse.

//  ViewController.swift

import Cocoa
let testWindow = TestWindow()

class ViewController: NSViewController {

func acceptsFirstMouse(for event: NSEvent?) -> Bool {
    return true
}

@IBAction func PushMeButton(_ sender: NSButton) {
    testWindow.show()
}

@IBAction func ChangeColorButton(_ sender: NSButton) {
    self.view.layer?.backgroundColor = NSColor.random.cgColor
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.wantsLayer = true;
}
override func mouseDown(with event: NSEvent) {
    self.view.layer?.backgroundColor = NSColor.random.cgColor
}
}


extension NSColor {

static var random: NSColor {
        let r:CGFloat  = .random(in: 0 ... 1)
        let g:CGFloat  = .random(in: 0 ... 1)
        let b:CGFloat  = .random(in: 0 ... 1)
        return NSColor(red: r, green: g, blue: b, alpha: 1)
    }
}

acceptsFirstMouse(for:) is a method on NSView , not NSViewController (or its superclasses). The fact that Swift did not require you to (and would not let you) use override on your function is an indication that you're not actually overriding a method. Also, if you had put a print() statement in your attempted override, you would see that it's never being called.

You need to use a subclass of NSView and override the method there.

Also, regarding:

When you do an 'override func acceptsFirstMouse' that returns true, the View should act as a first responder, even if it isn't in focus, right?

Well, not exactly. It means that clicks on the view are processed even if the window is inactive. Note, the state of the window is what's relevant, not the view. A view in an active window accepts clicks whether or not it's first responder (and isn't necessarily made first responder just because it's clicked). Also, first responder has other implications that are unrelated to clicks and have nothing to do with acceptsFirstMouse(for:) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM