您的位置:首页 > 其它

NSWindow.setFrame的坑

2016-02-05 20:14 323 查看

NSWindow.setFrame的坑

在OS X的开发中,我们一般使用NSWindow的setFrame来改变窗体的坐标和大小,而坐标和大小一般是靠动态计算得出,这里要讲讲setFrame的一些坑。

我们知道NSRect里的origin和size都是浮点型的,而像素点是整数的,没有说0.5个像素的,真要有0.5像素,在屏幕上的表现要么是0,要么就是1。下面我们来做个小实验:

我们先创建一个window

_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(450, 250, 400, 300) styleMask:NSTitledWindowMask | NSClosableWindowMask backing:NSBackingStoreBuffered defer:YES];
[_window makeKeyAndOrderFront:self];
LogRect(@"window.frame", _window.frame);


输出如下:

2016-01-23 17:05:38.306 testWindow[5057:78233] window.frame: {450.00,250.00,400.00,322.00}


可以看到,除了高度之外,其它值都按照我们提供的参数执行,至于高度为什么多了22,是因为我们设置了NSTitledWindowMask这个styleMask,窗体需要标题栏,高度为22。

接着通过setFrame来改变window的大小

[_window setFrame:NSMakeRect(450, 250, 400.5, 300) display:YES];
LogRect(@"window.changeSize", _window.frame);


输出如下:

2016-01-23 17:09:13.429 testWindow[5359:82569] window.changeSize: {450.00,250.00,401.00,300.00}


可以看到400.5被改成了401,难道NSWindow会把提供的值四舍五入吗?通过实验发现,400.1被改成400,而400.2被改成401,由此看来并非四舍五入,具体实现这边不讨论。所以我们在使用setFrame的时候需要注意提供的参数最后会不会得到我们想要的结果。

说完了大小,我们来看看坐标,这回我们通过setFrame来改变window的坐标。

[_window setFrame:NSMakeRect(450, 250.5, 400, 300) display:YES];
LogRect(@"window.changeOrigin", _window.frame);


通过前面的结果,我们想当然的认为结果应该是
(450,251,400,300)
。然而事实并非如此,我们看看输出:

2016-01-23 17:27:03.540 testWindow[6715:100007] window.changeOrigin: {450.00,250.00,400.00,301.00}


相当的意外,坐标没变,而高度却加了1,我们没有改高度的啊。百思不得其解,尝试其它y值看看,然后发现250.9的结果是
(450,251,400,300)
,250.8的结果是
(450,250,400,301)
。惊呆了有木有,在此只能劝大家动态计算的时候最好把浮点型转换成整形再传递给setFrame。如果有人知道这是为什么,烦请告知,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: