【问题标题】:Cocoa window position anomalyCocoa 窗口位置异常
【发布时间】:2011-10-28 12:05:10
【问题描述】:

我在屏幕上定位窗口时遇到了一个奇怪的问题。我想在屏幕上居中窗口,但我不知道该怎么做。这就是我所拥有的。窗口由主控制器从 nib 创建:

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

现在 IdentFormController 有 awakeFromNib() 方法,它会尝试定位窗口。为了简单起见,我只是尝试做 setFrameOrigin(NSMakePoint(0, 0))。发生的情况如下:

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

【问题讨论】:

  • ftf 是一个可怕的变量名称,以后可能会成为维护问题。

标签: objective-c cocoa nswindow


【解决方案1】:

所以据我了解,您希望窗口在屏幕上居中?

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

[window center];

这是最好的方法,但它会考虑视觉重量和 Dock 的存在。

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

// 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 的代码,因为它已经过测试并且是用户想要的期望看到,同样从设计的角度来看,作为一名设计师,我并不总是依赖实际中心作为光学中心所在的位置。

【讨论】:

    【解决方案2】:

    您可能与自动窗口定位发生冲突。你试过打电话吗

    [myWindowController setShouldCascadeWindows: NO];
    

    ?

    【讨论】:

      【解决方案3】:

      首先,听起来您需要在 NSWindow 的属性检查器中检查“关闭时释放”或“关闭时释放”。然后窗口会自行清理,您可以在自己的代码中删除对[self release] 的(有风险的)调用。

      awakeFromNib 在 nib 中的所有对象都已取消归档且插座已连接后调用,但设置窗口坐标可能为时过早。我相信 Cocoa 做了一些工作来自动将后续窗口定位在现有窗口的下方和右侧,这样新窗口就不会完全掩盖旧窗口。很可能在您在 awakeFromNib 中设置位置之后执行此操作,踩踏您的更改。

      设置窗口位置的最佳位置可能是在 NSWindow 委托方法之一中(可能是windowWillBecomeVisible:),或者可能就在您调用makeKeyAndOrderFront: 之前。

      【讨论】:

      • 由于某种原因,在检查关闭时发布时它不起作用。窗口可能已经被释放和清理,但是控制器呢?也许它没有被释放。一旦我添加了[自我释放] - 这件事终于奏效了。也许这是有风险的,但至少它可以工作,当你释放一个控制器时,它也会清理窗口。
      • 我想我将[self release] 误解为应用于 NSWindow 实例,而不是控制器。也许为了让事情更清楚,您的应用程序委托应该维护一个指向当前 IdentFormController 的指针。或者,如果您必须释放 self,请使用 autorelease,以便在运行循环结束之前不会释放对象。无论如何:将代码移动到委托方法有帮助吗?
      • 好吧,我还没有机会测试它,但我相信它会起作用。如果它适用于 [self release] - 那么它为什么不能从外部工作。顺便说一句:为什么[自我释放]有风险?如果我确定我不需要这个控制器并且什么都不会尝试访问它 - [self release] 可能会出现什么问题?
      • [self release] 是有风险的,因为您可能正在执行已释放对象的代码。如果这是您方法的最后一行,您可能大部分时间都可以,但不能保证。如果你可以打电话给autorelease,为什么还要冒险呢?
      • 关于调用[self release] 的讨论分散了您对主要问题的注意力:窗口定位。您是否使用像 windowWillBecomeVisible: 这样的委托方法而不是将代码放入 awakeFromNib 中取得任何成功?
      【解决方案4】:

      检查您是否可以将窗口的中心设置为屏幕的中心。并在其上设置窗口位置。它可能会奏效。

      【讨论】:

        猜你喜欢
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多