如何定位NSPopover

时间:2013-01-30 23:43:39

标签: cocoa nsview nsoutlineview nsviewcontroller nspopover

我有一个OSX应用程序,它使用NSViewController在我的NSView中交换进出视图。其中一个观点是NSOutlineView。我现在想要在用户双击outlineview中的行时显示NSPopover。目前我使用following approach来显示弹出窗口:

NSRect theRect = [[NSApp keyWindow] convertRectFromScreen: NSMakeRect(700, 400, 5, 5)];
[myPopover showRelativeToRect: theRect // Window Coordinates
                        ofView: [[NSApp keyWindow] contentView]
                 preferredEdge: NSMinYEdge];

这使得NSPopover显示在应用程序的底部。这有效,但我希望能够让弹出窗口正好位于NSOutlineView的单击行下方。我交换的每个视图都由NSViewController控制,我想我可以使用NSViewController的view属性识别我的视图位置。但是,如果我将[[NSApp keyWindow] contentView]替换为myViewController.view,则会收到视图没有窗口且NSPopover崩溃的错误。显然,我有麻烦1)在NSView中找到相对于主窗口的被点击行的坐标2)理解为什么我的视图没有窗口。如果有人有建议可以帮助我理解这些问题,我将非常感激。

更新06/02/2013 我仍然在努力解决我的问题,但我发现如果我通过MainWindowController(myControlledView)访问其属性,我可以获得正确的坐标。当我然后询问我的视图的原点和帧大小时,我得到正确的值。我的VC将自定义视图加载为NIB文件,当我要求加载视图的来源时,我得到(0,0)。我认为即使我将视图加载为NIB,视图相对于窗口的位置也将保持不变?我可以将视图原点传递给我的VC,从而正确设置NSPopover,但这看起来相当麻烦,我认为可以通过VC正确访问NIB加载的视图源。

managingViewController *vc = [viewControllers objectAtIndex:[viewIndex intValue]];
[self.currentViewController.view removeFromSuperview];
[self setCurrentViewController:vc];
[self.myControlledView addSubview:vc.view];
NSLog(@"My origin: %f %f",vc.view.frame.origin.x,vc.view.frame.origin.y);

这导致:My origin: 0.000000 0.000000并不是我想要的,而是:

NSLog(@"My origin: %f %f",self.myControlledView.frame.origin.x,self.myControlledView.frame.origin.y);

结果来自正确的来源:My origin: 176.000000 38.000000

显然,我不明白有关于视图和窗口的内容。任何帮助都是相关的。

感谢您的建议和帮助!干杯,特隆德

1 个答案:

答案 0 :(得分:3)

一旦我明白自己在做什么,事情就变得非常容易了。事实证明我有两个currentViewController的分配。一个在IB中分配,而一个在代码中分配。当我删除I​​B创建的VC时,我可以使用正确的代码启动视图进行交互,并且我能够使用(跟踪)鼠标的位置来定位我的NSPopover:

-(void)mouseMoved:(NSEvent *)theEvent {
    NSPoint p = theEvent.locationInWindow;
    self.myMouseX=[NSNumber numberWithFloat:p.x];
    self.myMouseY=[NSNumber numberWithFloat:p.y];
}

鼠标位置用于定义rect的坐标:

NSRect theRect = NSMakeRect([self.myMouseX floatValue] + 5,[self.myMouseY floatValue],1,1);

[myPopover showRelativeToRect: theRect // Window Coordinates
                       ofView: [[NSApp keyWindow] contentView]
                preferredEdge: NSMaxXEdge];

干杯,特隆德