5

我有一个带有文本字段和边框按钮的窗口。它是无边界和透明的,但问题会在任何窗口上重现。

该窗口的内容视图在 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];
}

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

在此处输入图像描述 在此处输入图像描述

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

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

4

3 回答 3

6

问题似乎是 [path setClip] 方法。我对此进行了注释,并且正确绘制了文本字段和按钮。

所以,我然后替换了这一行:

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

[gradient drawInBezierPath:path angle:270];

一切都很完美。按钮和文本字段按预期出现。

NSBezierPath 的类参考声明:

您应该避免使用此方法来调整剪切路径,因为它可能会扩展剪切路径超出封闭视图设置的范围。如果您确实使用此方法,请务必在修改剪切路径之前保存图形状态,并在完成后恢复图形状态。

该方法使用当前绕组规则来确定接收器的削波形状。此方法不影响接收器的路径。

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

于 2012-08-24T16:01:22.490 回答
0

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

它有效,但我对解决方案不满意。

我看不出有任何理由为什么上面不起作用。我在绘制视图时也遇到过类似的奇怪问题,所以我想知道它不起作用的真正原因。

于 2012-08-15T19:40:24.220 回答
0

我同意这很奇怪/烦人。有人会认为这只是层之间可能相互干扰的问题..但如果不执行以下操作似乎很难解决..

这是您描述的视图,一团糟。之后 - 通过界面生成器更改了一个简单的复选框..

在此处输入图像描述

在此处输入图像描述

我发现通过将有问题的控件封装在一个框或一个视图或诸如此类的东西中,然后单击界面构建器中的“核心动画”“setWantsLayer”按钮,将允许这些界面元素在没有所有杂乱无章的情况下发光。

在此处输入图像描述

一种愚蠢的解决方法......但实际上它有效 - 而且很容易。

PS - 我发现在解决此类问题时,使参数更具戏剧性(颜色等)会有所帮助 - 特别是如果您试图向人们描述出了什么问题..

于 2012-08-27T14:22:43.540 回答