2012-08-15 63 views
4

我有一个文本框和窗口按钮的窗口。它是无边界和透明的,但是这个问题在任何窗口都会重现。可可粉窗口的圆角渐变背景

该窗口的内容视图在IB中设置为绘制窗口背景的自定义类。

下面的代码:

- (void)drawRect:(NSRect)dirtyRect 
{ 
    [NSGraphicsContext saveGraphicsState]; 

    float cornerRadius = 10; 
    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:self.bounds xRadius:cornerRadius yRadius:cornerRadius]; 

    [path setClip]; 

    NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations: 
          [NSColor colorWithCalibratedRed:0.96f green:0.96f blue:0.96f alpha:1.00f], 0.0f, 
          [NSColor colorWithCalibratedRed:0.84f green:0.84f blue:0.84f alpha:1.00f], 1.0f, 
          nil]; 

    [gradient drawInRect:self.bounds angle:270]; 

    [NSGraphicsContext restoreGraphicsState]; 
} 

它会导致一些非常奇怪的文物,像消失的对象或文本字段的背景更改为窗口:

enter image description here enter image description here

这是怎么回事?我试图隔离它,我一直在玩这个“图形上下文状态保存”的东西(我不知道我是否理解正确),但问题依然存在。

我有XCode 4.4,SDK是10.7(我的操作系统也是如此),部署目标是10.6。这可能没有关系,但过去我一直在做类似的事情,而且我从来没有遇到过这样奇怪的问题。

+0

人说看起来像一个棘手的问题。 – loyalflow 2012-08-30 20:14:40

+0

是的。是的。 – radex 2012-08-31 06:11:43

回答

0

使其工作的一种解决方法是使用与self.bounds相同大小的窗口的-awakeFromNib或-init)NSImage,然后将此渐变绘制到图像中(使用图像的-lockFocus,-unlockFocus)。您可以使用window.backgroundColor = [NSColor colorWithPatternImage:image];将图像设置为背景。

它的工作原理,但我不满意解决方案。

我没有看到任何理由为什么上面不行。而且我也有类似的观点问题,所以我想知道为什么它不起作用的真正原因。

6

该问题似乎是[path setClip]方法。我评论了这一点,并正确绘制了文本字段和按钮。

所以,我再换成线:

[gradient drawInRect:self.bounds angle:270]; 

[gradient drawInBezierPath:path angle:270]; 

,一切都完美。按钮和文本字段按预期显示。

为NSBezierPath类别参考规定:

应该避免使用这种方法作为调节修剪路径的方法,因为它可以扩展超出由封闭视图中设置边界的剪切路径。如果确实使用此方法,请务必在修改剪切路径之前保存图形状态,并在完成后恢复图形状态。

该方法使用当前的缠绕规则来确定接收器的剪切形状。此方法不会影响接收器的路径。

没有真正解释你看到的问题,但让我看看我还能如何绘制渐变。

+0

谢谢你的回答,明天我会调查一下! – radex 2012-08-27 18:05:26

+0

嘿,它似乎工作! :)但是,如果我需要剪辑我的“圆角”贝塞尔路径脏肛门?我使用什么? + clipRect:NSBezierPath的?它似乎工作,但我不知道边缘情况... – radex 2012-08-28 19:32:29

+0

看着视图的drawRect,它正在传递一个dirtyRect为整个视图,然后dirtyRect为文本字段,基本上每次输入光标闪烁。我认为这就是剪辑影响文本字段和按钮的原因。所以问题是,你想什么时候将“圆角”应用到dirtyRect中。由于dortyRect将在不同时间表示视图的不同部分,因此如果使用dirtyRect,则会影响这些部分。 – 2012-08-29 20:07:09

0

我同意这很奇怪/讨厌。人们会认为,这只是一个层可能会干扰彼此的问题..但它似乎很难解决而不执行以下操作..

这里是您所描述的视图,搞砸了。和后 - 用一个简单的复选框通过界面生成器改变..

enter image description here

enter image description here

我已经发现,通过在一个盒子或视图或诸如此类的东西包围困扰控制,然后点击界面生成器中的“核心动画”“setWantsLayer”按钮将允许这些界面元素在没有所有kurfuffle的情况下发光。

enter image description here

一个愚蠢的解决方法的类...但在现实中它的工作原理 - 并且是容易的。

PS - 我发现它有助于使参数多一点点戏剧性的(颜色等)故障排除这种事情的时候 - 特别是如果你试图描述的人有什么错..

+0

嘿,谢谢你的提示。这似乎很有用,但对于一个特定的项目,我有这些问题使用CA层不是一个选项(因为该应用程序基于WebKit,出于某种原因,它看起来,当你使用图层时会出现混乱) – radex 2012-08-27 18:07:11

+0

有趣!似乎工作,但我得到了这样的通知:“当[NSGraphicsContext currentContext]为零时绘制图像没有意义,这是一个编程错误,断开void _NSWarnForDrawingImageWithNoCurrentContext()进行调试,只会记录一次。这可能会在未来破裂。“这是什么意思? – radex 2012-08-28 19:35:52

+0

你有没有“链接”到'QuartzCore.framework'?它也适用于**,没有** [NSGraphicsContext saveGraphicsState];'和[NSGraphicsContext restoreGraphicsState];'。就在那里!在混合可可和石英图画时,通常只需要担心自己的背景,或者将注意力集中在绘图例程中的特定“子指令”上。 – 2012-08-28 19:41:46