0

I need to catch mouseDown and keyDown events in a subclass of NSViewController and as it’s not possible (please, correct me if I’m wrong) I left my GameViewController class blank and put all it’s methods to a new GameView class. In the identity inspector of GameViewController.xib I set my class to GameView while File’s Owner is set to GameViewController. After all, my mouseDown method works, but keyDown doesn’t. I tried this:

- (BOOL) acceptsFirstResponder {
    return YES;
}

but it didn’t help.

Please, show me what to do.

UPD: Actually keyDown method works, but first I need to click somewhere on the blank space of my window and only then everything works as it was planned. Once again, mouseDown events are triggered with no problems. What may I be doing wrong?

new_user
  • 13
  • 3

1 Answers1

0

Your view accepts first responder when offered it, but nothing is attempting to make it the first responder until you click.

Set the window's initialFirstResponder some time before showing it. If you're using a NIB, it can be set there. Or you could do it programmatically.

After the window is shown, you can call [window makeFirstResponder:view] to make the view the first responder of its window.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Please, tell me where exactly should I put this call, I haven’t any files for NSWindow. I tried to put [self.view.window makeFirstResponder: gameView] in viewDidLoad of gameViewController, however, it also doesn’t seem to work. – new_user Feb 16 '15 at 16:39
  • If the view is being created separately from the window, which seems like the case since it's loaded by a view controller, you can't make it the first responder until the view is added to the window. When are you adding the view controller's view to the window and how? You would have to set either `initialFirstResponder` or call `-makeFirstResponder:` after the view is added to the window. – Ken Thomases Feb 16 '15 at 17:03
  • I use NSTabView object to switch my views (that's why I need NSViewController subclass) and it is placed in MainMenu.xib. Doesn't that mean that my views somehow are stuck to the window? – new_user Feb 17 '15 at 07:39
  • Well, with so much abstraction and automation, it can be hard to know when the view has been added to the window. You can use a custom view class and override `-viewDidMoveToWindow`. You can implement a tab view delegate and implement `-tabView:didSelectTabViewItem:`. If you're programmatically setting the tab view's selected tab, then you can put the call to `-makeFirstResponder:` immediately after switching to your game view's tab. – Ken Thomases Feb 17 '15 at 08:37
  • I reached some progress but with different approach. Apart from window with custom view, I have gameView and menuView in MainMenu.xib. When I click a button I call `[[self.window.contentView animator] replaceSubview:self with:(NSView *)gameView];` and `[self.window makeFirstResponder: (NSView *)gameView];`, similar in the reverse direction. And it works! Yes, here I can use my keyboard with no problem. Unfortunately, when I switch back to menuView and go to gameView second time, keyboard is broken again. What is the mystification with changing views this way? – new_user Feb 19 '15 at 13:04
  • Actually I don’t need `-makeFirstResponder: ` method, it works without it. – new_user Feb 19 '15 at 13:30
  • Sorry, it was just my fault. I added `[self.window makeFirstResponder: self];` to `-viewDidMoveToWindow’ and now it works fine. Thanks for your help! – new_user Feb 19 '15 at 14:06