NSWindow.setFrame的坑

来源:互联网 发布:sqlserver history 编辑:程序博客网 时间:2024/05/17 00:17

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。如果有人知道这是为什么,烦请告知,谢谢!

0 0
原创粉丝点击