And*_*ang 4 macos xcode cocoa objective-c
我想设计一个类似于弹出窗口的面板:当鼠标向下移动时,它可能会自行消除或隐藏.
但我不知道如何实现这一目标.我所知道的是,一个视图可以处理-mouseDown,-mouseUp等等.但是当按下鼠标在其他地方?我不知道如何抓住这个事件.
进一步讨论Bavarious:
我实际上正在研究状态栏.我跟着有一个问题.我研究的示例代码.
正如示例代码所做的那样,我覆盖了前面描述的视图并使用状态栏项的-setView:方法进行设置.我工作中的大多数代码都与示例代码完全相同.以下是我认为与我的混淆相关的代码的一些部分(使用BTW,ARC):
...
@property (nonatomic) SEL disclickAction; // Called when "dismissed"
@property (nonatomic) SEL action; // Called when selected
@property (nonatomic, assign) id target;
...
- (void)dealloc
{
NSLog(@"%@ dealloc", self);
[self invalidate];
//[super dealloc];
}
- (void)mouseDown:(NSEvent *)theEvent
{
[self setHighlighted:![self isHighlighted]];
if (_target && _action &&
[_target respondsToSelector:_action])
{
[NSApp sendAction:_action to:_target from:self];
}
}
// Here is the code that Bavarious taught me:
- (void)setDisclickAction:(SEL)disclickAction
{
_disclickAction = disclickAction;
if (!_mouseEventMonitor)
{
if (_disclickAction)
{
self.mouseEventMonitor = [NSEvent
addLocalMonitorForEventsMatchingMask:(NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask)
handler:^NSEvent *(NSEvent *event) {
if (event.window != self.window)
{
[self actionDisclick:nil];
}
return event;
}];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(actionDisclick:)
name:NSApplicationDidResignActiveNotification
object:nil];
}
}
else if (!_disclickAction) // cancel operation
{
[NSEvent removeMonitor:_mouseEventMonitor];
_mouseEventMonitor = nil;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的屏幕,例如(黄色卡通脸是我的状态栏项目):http: //oi43.tinypic.com/35cr1nb.jpg
将鼠标放在上方位置时:
A:mouseDown调用视图,然后通知鼠标按下事件的本地观察者.
B:通知鼠标停止事件的本地观察者.
C:通知辞职申请事件.
D:没有事件.鼠标停止事件的本地观察者都没有.这就是问题所在.
小智 9
AppKit负责将鼠标事件转发到发生这些事件的窗口/视图.如果您希望在其他位置捕获鼠标事件,可以使用本地事件监视器.
在应该实现此行为的类中,可能是拥有该面板的类,定义一个实例变量或声明的属性来保存事件监视器实例:
@property (nonatomic, strong) id mouseEventMonitor;
Run Code Online (Sandbox Code Playgroud)
显示面板时,添加鼠标事件监视器:
self.mouseEventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:(NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask) handler:^NSEvent *(NSEvent *event) {
if (event.window != self.panelWindow)
[self dismissPanel];
return event;
}];
Run Code Online (Sandbox Code Playgroud)
关闭面板时,请删除鼠标事件监视器:
- (void)dismissPanel {
if (self.mouseEventMonitor != nil) {
[NSEvent removeMonitor:self.mouseEventMonitor];
self.mouseEventMonitor = nil;
}
// …
}
Run Code Online (Sandbox Code Playgroud)
如果需要测试特定视图而不是包含面板的整个窗口,请使用-[NSView hitTest:]以检查鼠标位置(event.locationInWindow)是属于该视图还是属于其子视图.
编辑:如果用户在应用程序窗口外单击,则关闭面板,观察NSApplicationDidResignActiveNotification,每当应用程序重新启动其活动状态时发布该面板,这意味着某些其他应用程序已变为活动状态.当您显示面板时:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissPanel) name:NSApplicationDidResignActiveNotification object:nil];
Run Code Online (Sandbox Code Playgroud)
当你解雇小组时:
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidResignActiveNotification object:nil];
Run Code Online (Sandbox Code Playgroud)
编辑:要处理用户是否单击了菜单栏(NSApplicationDidResignActiveNotification由于应用程序仍处于活动状态而未发布)的情况,您还必须观察NSMenuDidBeginTrackingNotification主菜单发布的情况[NSApp mainMenu].当您显示面板时:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissPanel) name:NSMenuDidBeginTrackingNotification object:[NSApp mainMenu]];
Run Code Online (Sandbox Code Playgroud)
当你解雇小组时:
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMenuDidBeginTrackingNotification object:[NSApp mainMenu]];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2038 次 |
| 最近记录: |