我一直在使用这里的示例创建一个自定义无标题栏窗口:
Drawing a custom window on Mac OS X
我发现这是我在Leopard,Snow Leopard和Lion中创建无标题栏窗口的唯一方法,其他方法在Leopard或Lion上都无法正常工作。 (如果我尝试通过正常的NSWindow和IB调用无标题栏的窗口,它将不再在Leopard中启动)
到目前为止,这个自定义无标题栏的窗口无处不在,但我无法居中,只能在Interface Builder中找到一个固定的位置。
使用[窗口中心]将正常的NSWindow *窗口实现集中在一起相当容易,但是我发现在这个自定义窗口子类上没有任何效果,这个窗口不是通过Interface Builder从nib创建的。
我已尝试过NSWindow的一些内容,但似乎没有任何效果。
任何想法?
答案 0 :(得分:16)
CGFloat xPos = NSWidth([[window screen] frame])/2 - NSWidth([window frame])/2;
CGFloat yPos = NSHeight([[window screen] frame])/2 - NSHeight([window frame])/2;
[window setFrame:NSMakeRect(xPos, yPos, NSWidth([window frame]), NSHeight([window frame])) display:YES];
这将它放在屏幕的文字中心,而不考虑扩展坞和菜单栏占用的空间。如果您想这样做,请将[[window screen] frame]
更改为[[window screen] visibleFrame]
。
答案 1 :(得分:4)
问题应该是[window center]
不起作用的原因;但假设是这种情况使用NSScreen
来获取屏幕坐标,进行数学计算,并直接使窗口居中。
答案 2 :(得分:3)
extension NSWindow {
public func setFrameOriginToPositionWindowInCenterOfScreen() {
if let screenSize = screen?.frame.size {
self.setFrameOrigin(NSPoint(x: (screenSize.width-frame.size.width)/2, y: (screenSize.height-frame.size.height)/2))
}
}
}
答案 3 :(得分:1)
Objective-C
@Wekwa的答案更具可读性
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSWindow * window = NSApplication.sharedApplication.windows[0];
CGFloat xPos = NSWidth(window.screen.frame)/2 - NSWidth(window.frame)/2;
CGFloat yPos = NSHeight(window.screen.frame)/2 - NSHeight(window.frame)/2;
[window setFrame:NSMakeRect(xPos, yPos, NSWidth(window.frame), NSHeight(window.frame)) display:YES];
}
答案 4 :(得分:0)
Swift版本:可以为同一个
编写一个简单的静态实用程序函数static func positionWindowAtCenter(sender: NSWindow?){
if let window = sender {
let xPos = NSWidth((window.screen?.frame)!)/2 - NSWidth(window.frame)/2
let yPos = NSHeight((window.screen?.frame)!)/2 - NSHeight(window.frame)/2
let frame = NSMakeRect(xPos, yPos, NSWidth(window.frame), NSHeight(window.frame))
window.setFrame(frame, display: true)
}
}
答案 5 :(得分:0)
我偶然发现了同一个问题。对我有用的是在调用isRestorable
之前在false
对象上将NSWindow
设置为center()
。
答案 6 :(得分:0)
我总是发现用 screen.frame
将窗口居中会导致窗口感觉好像它离屏幕底部太近了。这是因为 Dock 的大小几乎是状态/菜单栏的 3 倍(分别约为 70-80 像素和 25 像素)。
这会导致窗口出现好像它位于屏幕底部下方,因为我们的眼睛不会自动调整状态栏(1x 大小)和 Dock( ~3x 大小)。
出于这个原因,我总是选择使用 screen.visibleFrame
,因为它绝对感觉更集中。 visibleFrame
同时考虑状态栏和 Dock 大小,并计算这两个对象之间框架的中心点。
extension NSWindow {
/// Positions the `NSWindow` at the horizontal-vertical center of the `visibleFrame` (takes Status Bar and Dock sizes into account)
public func positionCenter() {
if let screenSize = screen?.visibleFrame.size {
self.setFrameOrigin(NSPoint(x: (screenSize.width-frame.size.width)/2, y: (screenSize.height-frame.size.height)/2))
}
}
/// Centers the window within the `visibleFrame`, and sizes it with the width-by-height dimensions provided.
public func setCenterFrame(width: Int, height: Int) {
if let screenSize = screen?.visibleFrame.size {
let x = (screenSize.width-frame.size.width)/2
let y = (screenSize.height-frame.size.height)/2
self.setFrame(NSRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height)), display: true)
}
}
/// Returns the center x-point of the `screen.visibleFrame` (the frame between the Status Bar and Dock).
/// Falls back on `screen.frame` when `.visibleFrame` is unavailable (includes Status Bar and Dock).
public func xCenter() -> CGFloat {
if let screenSize = screen?.visibleFrame.size { return (screenSize.width-frame.size.width)/2 }
if let screenSize = screen?.frame.size { return (screenSize.width-frame.size.width)/2 }
return CGFloat(0)
}
/// Returns the center y-point of the `screen.visibleFrame` (the frame between the Status Bar and Dock).
/// Falls back on `screen.frame` when `.visibleFrame` is unavailable (includes Status Bar and Dock).
public func yCenter() -> CGFloat {
if let screenSize = screen?.visibleFrame.size { return (screenSize.height-frame.size.height)/2 }
if let screenSize = screen?.frame.size { return (screenSize.height-frame.size.height)/2 }
return CGFloat(0)
}
}
将现有窗口定位到可见框的中心。
window!.positionCenter()
在visibleFrame的中心设置一个带有尺寸的新窗口框架
window!.setCenterFrame(width: 900, height: 600)
使用 xCenter()
和 yCenter()
获得 visibleFrame
的中心 x-y 点。
let x = self.view.window?.xCenter() ?? CGFloat(0)
let y = self.view.window?.yCenter() ?? CGFloat(0)
self.view.window?.setFrame(NSRect(x: x, y: y, width: CGFloat(900), height: CGFloat(600)), display: true)
函数示例
override func viewDidLoad() {
super.viewDidLoad()
initWindowSize(width: 900, height: 600)
}
func initWindowSize(width: Int, height: Int) {
let x = self.view.window?.xCenter() ?? CGFloat(0)
let y = self.view.window?.yCenter() ?? CGFloat(0)
self.view.window?.setFrame(NSRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height)), display: true)
}