2012-08-15 33 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