keyDown не вызывается
У меня есть собственный NSView под названием SurfaceView. Это contentView NSWindow и он обрабатывает основные события, такие как щелчок мыши и рисование. Но не имеет значения, что я делаю, он не обрабатывает функцию keyDown. Я уже переопределил acceptsFirstResponder, но ничего не происходит.
Если это имеет значение, я запускаю приложение с помощью пользовательского цикла NSEvent, показанного ниже:
NSDictionary* info = [[NSBundle mainBundle] infoDictionary];
NSString* mainNibName = [info objectForKey:@"NSMainNibFile"];
NSApplication* app = [NSApplication sharedApplication];
NSNib* mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]];
[mainNib instantiateNibWithOwner:app topLevelObjects:nil];
[app finishLaunching];
while(true)
{
NSEvent* event = [app nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate date] inMode:NSDefaultRunLoopMode dequeue:YES];
[app sendEvent:event];
// Some code is execute here every frame to do some tasks...
usleep(5000);
}
Вот код SurfaceView:
@interface SurfaceView : NSView
{
Panel* panel;
}
@property (nonatomic) Panel* panel;
- (void)drawRect:(NSRect)dirtyRect;
- (BOOL)isFlipped;
- (void)mouseDown:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
- (void)keyDown:(NSEvent *)theEvent;
- (BOOL)acceptsFirstResponder;
- (BOOL)becomeFirstResponder;
@end
-
@implementation SurfaceView
@synthesize panel;
- (BOOL)acceptsFirstResponder
{
return YES;
};
- (void)keyDown:(NSEvent *)theEvent
{
// this function is never called
};
...
@end
Вот как я создаю вид:
NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(left, top, wide, tall) styleMask:NSBorderlessWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:NO];
...
[window makeKeyAndOrderFront:nil];
SurfaceView* mainView = [SurfaceView alloc];
[mainView initWithFrame:NSMakeRect(0, 0, wide, tall)];
mainView.panel = panel;
[window setContentView:mainView];
[window setInitialFirstResponder:mainView];
[window setNextResponder:mainView];
[window makeFirstResponder:mainView];
3 ответа
Я узнал, что мешало keyDown
событие от того, чтобы быть названным. Это было NSBorderlessWindowMask
маска, это предотвращает, чтобы окно стало ключом и главным окном. Итак, я создал подкласс NSWindow
называется BorderlessWindow
:
@interface BorderlessWindow : NSWindow
{
}
@end
@implementation BorderlessWindow
- (BOOL)canBecomeKeyWindow
{
return YES;
}
- (BOOL)canBecomeMainWindow
{
return YES;
}
@end
В дополнение к ответу: установите флажок IB для NSWindow
,
Title Bar
должны быть проверены. Это похоже на NSBorderlessWindowMask
В моем случае мне пришлось переопределить метод как для NSView, так и для NSWindow (создал настройку обоих). В NSWindow вkeyDown
мне пришлось позвонить
- (void) keyDown:(NSEvent *) event {
if (self.firstResponder != self) {
[self.firstResponder keyDown:event];
}
}
чтобы событие достигло представления. Конечно, я должен был также позвонитьmakeFirstResponder
сначала в NSWindow и передайтеcontentView
к этому:
[window makeFirstResponder: [window contentView] ];