NSWindow纹理背景与NStextField

时间:2011-10-17 14:49:02

标签: cocoa window nswindow nstextfield

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

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

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

当您构建并运行它时,请注意窗口的背景,初始一个很好,现在使窗口变大,它将切换到更暗的背景。

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

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

2 个答案:

答案 0 :(得分:11)

它似乎与Windows“内容边框”设置有关。如果在IB中将其设置为none,则不会发生问题,但也会修改渐变。对我来说似乎是一个错误。也许是雷达的时间?

答案 1 :(得分:4)

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

我希望在此帖子中添加更多内容,以便其他开发人员发现他们遇到的问题相同,以后可能会更容易解决该问题。

就我而言,我构建了一个带有纹理窗口的应用程序。与Dimillian77的问题类似,我的应用程序的主窗口背景纹理受到子视图的大小调整和放置的影响,在我的例子中,这些是主窗口的各种NSView子视图&#39 ; s NSWindowController根据用户访问的应用程序区域进行切换。由于NSView子视图的大小和位置对于每个子视图略有不同,因此当用户在每个视图之间切换时,这相应地使得梯度错误更明显,因为主窗口的背景渐变将在子窗口后面跳跃-view。

有趣的是,渐变问题仅在转换到OS X 10.7 Snow Leopard之后出现 - 相同的,未修改的源代码和.xib / .nib文件在任何早期版本的OS X上都没有导致此问题。这看起来似乎同意cocoahero的建议,这个问题可能是一个值得雷达报告的新bug - 也许我们会发现它已经在Mountain Lion中修复了?

实际上,我的应用程序的主要NSWindow和几个支持窗口都设置为使用" Textured" (金属色)背景选项,但只有在转移到Snow Leopard之后才会出现渐变的错误'清单。

在找到这篇文章之前,我偶然发现了解决问题的唯一方法。问题是注意到如果窗口有" Resize"控制启用渐变错误消失!

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

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

我发现设置"内容边框"设置为"自定义"并设置" Top"和"底部"内容与" 1"解决了崩溃问题,虽然在使用" Custom"保存和编译应用程序后很奇怪。设置到位后,我通过实验发现我能够改变"自定义边框"设置为"无"并编译应用程序并使其在第二次编译时正常运行。

然而,更改"内容边框"除了" Autosize"以外的任何事情在10.7和#34之前的Mac OS X上导致了数十个非法配置:自动布局。 XCode中的错误,以及一些"属性不可用:除了Autosize for Top / Bottom Content Border属性之外的值,在10.6和#34之前的Mac OS X版本上;错误 - 所有与“内容边界”相关的错误" property(我的部署目标设置为OS X 10.6而不是10.7)。因此,恢复了对错误的另一种解决方案的搜索,这使我得到了下面详述的解决方案。我发现的解决方案,至少在OS X 10.7上,是设置"内容边界"每个带纹理的窗口返回" Autosize"在Interface Builder中,改为覆盖代码中的内容边框设置(在我的例子中,将此代码放入我的每个纹理窗口的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中渲染" Textured" Windows,修改任何覆盖内容边框的代码可能是明智的,这样这些代码只能在运行OS X 10.7的系统上执行(如果在Mountain Lion中问题仍未解决,可能会在未来的OS X版本中执行)。

我希望这篇文章很有用,这个错误确实令人困惑,并且比我希望解决的时间更长。由于似乎有这样稀疏的问题记录,我觉得值得花时间发布我的发现,希望它能节省其他时间,并希望通过在线搜索找到更多的曝光和关键词。

谢谢必须去cocoahero,因为没有他们的回答,我和其他许多人仍然在努力解决这个问题。