2010-10-03 27 views
2

我試圖做一個更復雜的UILabels繪圖(或UIView,把UILabel放在頂部,應該是必需的)背景。因爲我想要這個在用戶更改iPhone方向時自動調整大小,所以我試圖在子類drawRect函數中實現它。如果可能的話,我希望能夠在代碼中調整這一切,而不需要模式圖像。UIView CGGradient修剪繪製「框架」

我得到了一些提示,從一些關於這個問題前職位:

Gradients on UIView and UILabels On iPhoneMake Background of UIView a Gradient Without Sub Classing

遺憾的是他們都錯過了目標,因爲我想梯度自定義繪製結合起來。我想讓CGGradient被我正在繪製的線框剪裁(可以在圓角處看到),但是我無法做到這一點。

另一種方法是使用CAGradientLayer,它似乎工作得很好,但這需要對框架進行旋轉時的一些調整,並且漸變層似乎在文本的頂部繪製,無論我如何嘗試。

我的問題爲此是雙重

  • 如何修改下面的代碼,以使梯度剪輯繪製的「幀」
  • 我如何CAGradientLayer繪製的UILabel的文本後面(或我必須把落後的UILabel一個UIView與CAGradientLayer爲背景)

這裏是我的drawRect功能:

- (void)drawRect:(CGRect)rect { 
// Drawing code 
CGContextRef c = UIGraphicsGetCurrentContext(); 
CGContextSetFillColorWithColor(c, [[UIColor clearColor] CGColor]); 
CGContextSetStrokeColorWithColor(c, [strokeColor CGColor]); 
CGContextSetLineWidth(c, 1); 

CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ; 
CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect) ; 
minx = minx + 1; 
miny = miny + 1; 

maxx = maxx - 1; 
maxy = maxy - 1; 

CGGradientRef glossGradient; 
CGColorSpaceRef rgbColorspace; 
size_t num_locations = 2; 
CGFloat locations[2] = { 0.0, 1.0 }; 
CGFloat components[8] = { 0.6, 0.6, 0.6, 1.0, // Start color 
0.3, 0.3, 0.3, 1.0 }; // End color 

rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations); 

CGRect currentBounds = [self bounds]; 
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f); 
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds),   CGRectGetMidY(currentBounds)); 
CGPoint lowCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds)); 

CGContextDrawLinearGradient(c, glossGradient, topCenter, midCenter, 0); 

CGGradientRelease(glossGradient); 
CGColorSpaceRelease(rgbColorspace); 

CGContextMoveToPoint(c, minx, midy); 
CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE_INFO); 
CGContextAddArcToPoint(c, maxx, miny, maxx, midy, ROUND_SIZE_INFO); 
CGContextAddArcToPoint(c, maxx, maxy, midx, maxy, ROUND_SIZE_INFO); 
CGContextAddArcToPoint(c, minx, maxy, minx, midy, ROUND_SIZE_INFO); 

// Close the path 
CGContextClosePath(c); 
// Fill & stroke the path 
CGContextDrawPath(c, kCGPathFillStroke);     
//  return; 

[super drawRect: rect]; 
+0

基本上,我想知道是否有辦法將Gradient限制到某個邊界,有點像CALayer的maskToBounds標誌。 – jollyCocoa 2010-10-03 08:10:00

+0

使用CAGradientLayer似乎足以解決簡單的矩形,漸變背景,但問題仍然存在,如果可能的話,完成與自定義繪圖相同的任務...(如果我想繪製一個非方形邊框的自定義邊框背景使用CGContextAddLineToPoint()和CGContextAddArcToPoint()。是否有可能用漸變填充邊界內容,這將如何完成)? – jollyCocoa 2010-10-04 07:32:26

回答

3

你所尋找的是CGContextClip()

創建路徑和梯度在你的代碼,然後

CGContextClip(c); 
CGContextDrawLinearGradient(c, glossGradient, topCenter, midCenter, 0); 
CGGradientRelease(glossGradient); 

(刪除舊的呼叫CGContextDrawLinearGradient)

還記得保存和恢復您的上下文之前和之後你做任何剪輯

如果你的剪輯是從你想要的反轉,嘗試CGContextEOClip()(或繪製你的路徑反向或der)

+0

謝謝,我會盡快研究它! – jollyCocoa 2010-10-28 13:11:59

+0

我回到這個話題。已經有一段時間了,我希望你會讀到這個。我設法根據路徑創建了帶有限幅邊界的漸變,但仍然存在一個我無法解決的問題。在上面的代碼中,我創建了一個圓角矩形的路徑。在原始繪圖中,這產生了具有繪製邊界和另一種填充顏色的圖形。現在我想爲此形狀添加自定義漸變。問題在於,您的修補程序可以讓我使用上面未剪切的漸變繪製原始形狀,或者只將漸變剪裁到路徑上。那麼我該如何實現這兩個目標? – jollyCocoa 2011-01-23 17:07:24

+0

我解決了它。解決的辦法是在第一條路線被擊中後畫出一條新的道路。非常感謝! – jollyCocoa 2011-01-23 19:09:37