UIView CGGradient剪裁为“绘制”;“框架”;

UIView CGGradient剪裁为“绘制”;“框架”;,uiview,drawing,gradient,drawrect,Uiview,Drawing,Gradient,Drawrect,我正在尝试绘制一个更复杂的UILabels(或者UIView,如果需要的话,将UILabel放在顶部)背景图。由于我希望在用户更改iPhone方向时自动调整大小,因此我尝试在子类drawRect函数中实现这一点。如果可能的话,我希望能够在代码中对这一切进行调优,省去对模式图像的需要 我从以前关于这个主题的一些帖子中得到了一些提示: 及 不幸的是,它们都没有达到目标,因为我想将渐变与自定义绘图相结合。我希望CGGradient被我正在绘制的线框剪裁(在圆角处可见),但我无法做到这一点 另一种选

我正在尝试绘制一个更复杂的UILabels(或者UIView,如果需要的话,将UILabel放在顶部)背景图。由于我希望在用户更改iPhone方向时自动调整大小,因此我尝试在子类drawRect函数中实现这一点。如果可能的话,我希望能够在代码中对这一切进行调优,省去对模式图像的需要

我从以前关于这个主题的一些帖子中得到了一些提示:

不幸的是,它们都没有达到目标,因为我想将渐变与自定义绘图相结合。我希望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]; 

您要查找的是CGContextClip()

在代码中创建路径和渐变,然后

CGContextClip(c);
CGContextDrawLinearGradient(c, glossGradient, topCenter, midCenter, 0);
CGGradientRelease(glossGradient);
(删除对CGContextDrawLinearGradient的旧调用)

还记得在进行任何剪辑之前和之后保存和恢复上下文


如果剪辑与所需相反,请尝试CGContextEOClip()(或按相反顺序绘制路径)

基本上,我想知道是否有办法将渐变限制在某个边界,有点像CALayer的maskToBounds标志。使用CAGradientLayer似乎足以解决简单的矩形渐变背景,但问题仍然存在,如果有可能完成与自定义绘图相同的任务。。。(例如,如果我想使用CGContextAddLineToPoint()和CGContextAddArcToPoint()绘制一个带有非方形边框的自定义边框背景,该怎么办?是否可以用渐变填充边框内容,以及如何实现)?谢谢,我会尽快研究它!我回到这个话题上来。已经有一段时间了,我希望你能读到这篇文章。我根据路径创建了一个带有剪裁边界的渐变,但是我仍然有一个问题没有解决。在上面的代码中,我创建了一个圆角矩形的路径。在原始图形中,这导致图形具有绘制的边界和另一种填充颜色。现在我想给这个形状添加一个自定义渐变。问题是,你的修正要么让我用上面未剪裁的渐变绘制原始形状,要么只将渐变剪裁到路径上。那么我如何做到这两个呢?我解决了。解决办法是在第一条路被开辟之后再画一条新路。非常感谢!