带有NStextField的NSWindow纹理背景



我有一个超级奇怪的问题。我想要一个纹理窗口,它有正常的渐变颜色。我有一个NSTextField在这个窗口,文本字段注定是一个URL输入字段,所以它需要是大的。问题是,当它太大时(大约超过窗口宽度的1/3),它只是切换纹理窗口,绘制一个更暗的渐变版本。

这里是一个示例项目(非常简单…)供您测试。

http://raven.ipodtutofast.com/test.zip

当你将构建和运行它注意到窗口的背景,最初的一个是好的,现在使窗口更大,它会切换到一个更暗的背景。

我真的不知道如何解决这个问题。

更新:感谢cocoahero,如果在IB的内容边界设置中您选择自定义,您可以将渐变高度设置为任何您想要的,以前从未注意到过。

这似乎与windows的"content border"设置有关。当它在IB中设置为none时,问题不会发生,但也会修改梯度。对我来说好像是个bug。也许是时候安装雷达了?

在我的应用程序中,我也遇到了上面提到的纹理NSWindows的渐变问题,但我花了很长时间才找到这篇文章来帮助解决这个问题。

我希望在这篇文章中添加更多的内容,这样如果其他开发人员发现他们遇到了同样的问题,那么解决方案可能会在将来更容易地出现。

在我的例子中,我用一组纹理窗口构建了一个应用程序。与Dimillian77的问题类似,我的应用程序的主窗口背景纹理受到子视图的大小和位置的影响,在我的情况下,这些是主窗口的NSWindowController根据用户正在访问的应用程序的哪个区域切换进/退出的各种NSView子视图。由于NSView子视图的大小和位置在每个子视图之间略有不同,因此当用户在每个视图之间切换时,这相应地使得梯度错误更加明显,因为主窗口的背景梯度会在子视图后面跳跃。

有趣的是,梯度问题只出现在转换到OS X 10.7雪豹之后-相同的,未修改的源代码和。xib/。nib文件在任何早期版本的OS x上都不会导致这个问题。这似乎与cocoahero的建议一致,这个问题可能是一个值得雷达报告的新bug——也许我们会发现它在Mountain Lion中已经修复了?

事实上,我的应用程序的主NSWindow和几个支持窗口都被设置为使用"纹理"(金属)背景选项,但只有在迁移到雪豹之后,渐变的"错误"才出现。

在找到这篇文章之前,我偶然发现"解决"这个问题的唯一方法是注意到,如果窗口启用了"调整大小"控件,那么梯度错误就会消失!

然而,我不希望我的特定应用程序窗口是可调整大小的,而且我可以禁用-(void)setShowsResizeIndicator:(BOOL)showResizeIndicator的标题栏"调整大小"控件,并通过拦截对-(NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize的调用来覆盖用户试图调整窗口大小的尝试,这显然不是一个优雅的解决方案或方法。这个解决方案失败了,特别是当窗口仍然显示其调整大小的鼠标光标时(我无法隐藏),因为这些会让用户感到困惑,因为我在代码中重写了任何调整窗口大小的尝试。

值得庆幸的是,cocoahero的解决方案将"Content Border"设置为"None",立即使渐变问题在Interface Builder(与Xcode 4.3.3集成的版本)中消失,但至少在我的情况下,在进行此更改后最初编译和运行应用程序时,一旦加载。xib文件,应用程序就会崩溃。下面的错误信息出现在跟踪中:"setAutorecalculatesContentBorderThickness:forEdge:可能不会在非纹理窗口中调用NSMaxYEdge "。

我发现将"Content Border"设置为"Custom"并将"Top"one_answers"Bottom"内容边框设置为"1"解决了崩溃问题,尽管奇怪的是,在保存和编译了"Custom"设置的应用程序后,我发现通过实验,我可以将"Custom Border"设置为"None"并编译应用程序并使其在第二次编译时正常运行。

然而,将"内容边界"更改为"自动大小"以外的任何东西导致XCode中的数十个"非法配置:10.7之前Mac OS X上的自动布局"错误,以及许多"属性不可用:10.6之前Mac OS X版本上的顶部/底部内容边界属性的自动大小以外的值"错误-所有这些都与"内容边界"属性有关(我的部署目标设置为OS X 10.6而不是10.7)。因此,继续寻找另一个解决错误的方法,这使我找到了下面详细说明的解决方案。我找到的解决方案,至少在OS X 10.7上,是将每个纹理窗口的"内容边界"设置回"自动大小",并在代码中重写内容边界设置(在我的情况下,通过将此代码放入我的每个纹理窗口的NSWindowController类):

// windowDidLoad is called when the window has loaded but before it's displayed...
-(void)windowDidLoad
{
// set the content border thickness to 0 for both the top and bottom window edges
[[super window] setContentBorderThickness:0 forEdge:NSMaxYEdge]; // top border
[[super window] setContentBorderThickness:0 forEdge:NSMinYEdge]; // bottom border
// disable the auto-recalculation of the window's content border
[[super window] setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
[[super window] setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
}

请注意,你只能在纹理窗口上设置顶部内容边框的厚度,如果你试图通过代码或通过其他NSWindow类型的接口构建器设置它,系统将引发异常,可能导致应用程序崩溃。

根据NSWindow文档:"在非纹理窗口中调用setContentBorderThickness:forEdge:传递NSMaxYEdge将引发异常。仅在纹理窗口中设置上边缘的内容边框厚度有效。"

由于渐变问题似乎确实是OS X 10.7渲染"纹理"窗口的新错误,因此修改覆盖内容边界的任何代码可能是明智的,以便此类代码仅在运行OS X 10.7的系统上执行(如果问题在Mountain Lion中未修复,则可能在未来的OS X版本中执行)。

我希望这篇文章是有用的,这个bug是真正令人困惑的,花了比我希望解决的更长的时间。由于这个问题的文档似乎很少,我觉得花点时间发表我的发现是值得的,希望它能节省别人的时间,并希望通过在线搜索让这个问题更多地曝光和找到关键字。

必须感谢cocoahero,因为如果没有他们的答案,我和其他许多人可能还在努力解决这个问题。

最新更新