2010-02-12 79 views
10

我有一个奇怪的问题,在屏幕上定位一个窗口。我想将窗口居中在屏幕上,但我不知道该怎么做。这是我得到的。由主控制器从笔尖创建窗口:可可窗口位置异常

IdentFormController *ftf = [[IdentFormController alloc] initWithWindowNibName:@"IdentForm"]; 
[[ftf window] makeKeyAndOrderFront:self]; 

现在IdentFormController具有其中它试图定位窗口awakeFromNib()方法。为了简单起见,我只是试图做setFrameOrigin(NSMakePoint(0,0))。会发生什么如下:

我第一次创建这个窗口,一切都按预期工作。但是如果我在释放之前再次创建它,它会开始出现在随机位置。它为什么这样做?

+5

* ftf *是一个变量的可怕名称,并可能在稍后成为维护问题。 – 2010-03-21 14:05:03

回答

1

首先,听起来好像您需要在NSWindow的财产检查员中检查“关闭时的dealloc”或“关闭时释放”。然后,窗口将自行清理,您可以在自己的代码中删除(风险)呼叫[self release]

awakeFromNib在来自笔尖的所有对象都被解除存档并且插座已连接之后被调用,但这可能为设置窗口坐标提供了太早的时间。我相信可可做了一些工作来自动将后面的窗口放在现有窗口的右下方,以便新窗口不会完全遮挡旧窗口。在你设置了awakeFromNib中的位置之后,可能会这样做,跺脚你的改变。

设置窗口位置的最佳位置可能在NSWindow代表方法之一(或许是windowWillBecomeVisible:),或者可能在您拨打makeKeyAndOrderFront:之前。

+0

由于某种原因,当关闭发布时被检查不起作用。该窗口可能已经释放并清理,但控制器如何?也许它没有被释放。只要我添加了[自我释放] - 这个事情终于奏效了。也许这是有风险的,但至少它有效,当你释放一个控制器时 - 它也会清理窗口。 – Marius 2010-02-23 13:54:53

+0

我想我误解了'[self release]'适用于NSWindow实例,而不是控制器。也许为了让事情更清楚,你的应用程序委托应该维护一个指向当前IdentFormController的指针。或者如果你必须释放self,使用'autorelease',这样对象不会被释放,直到运行循环结束。无论如何:是否将代码移至委托方法帮助? – benzado 2010-02-23 15:04:11

+0

那么,我还没有机会测试它,但我相信它会工作。如果它与[自我释放]一起工作 - 那么为什么它不能从外部工作。顺便说一句:为什么[自我释放]有风险?如果我确定我不需要这个控制器,并且没有任何东西会尝试访问它,但[自释放]会发生什么问题? – Marius 2010-02-25 12:41:10

0

看看您是否可以用屏幕中心设置窗口中心。并在上面设置窗口位置。它可能会解决。

14

因此,据我了解,你想要在屏幕上居中窗口?

那么假设NSWindow *window是你的窗口对象,然后有两种方法...

[window center]; 

这是做到这一点的最好方式,但它会OFSET考虑到视觉重量和码头的存在。

如果你想死点那么这将工作...

// Calculate the actual center 
CGFloat x = (window.screen.frame.size.width - window.frame.size.width)/2; 
CGFloat y = (window.screen.frame.size.height - window.frame.size.height)/2; 

// Create a rect to send to the window 
NSRect newFrame = NSMakeRect(x, y, window.frame.size.width, window.frame.size.height); 

// Send message to the window to resize/relocate 
[window setFrame:newFrame display:YES animate:NO]; 

此代码是未经测试,但它给你的,你需要做的就是这件事的工作,你所希望的方式是什么一个公平的想法,我个人建议你坚持使用Apple的代码,因为它已经过测试,并且是用户期望看到的,从设计角度来看,作为设计师我自己并不总是依赖实际中心来成为光学中心是。

5

您可能会遇到自动窗口定位的问题。您是否尝试致电

[myWindowController setShouldCascadeWindows: NO];