首页 文章

UIView CGGradient剪裁为绘制“框架”

提问于
浏览
2

我正在尝试制作更复杂的UILabels(或UIView,将UILabel置于顶部,如果需要)背景 . 由于我希望在用户更改iPhone方向时自动调整大小,我试图在子类drawRect函数中实现它 . 我希望能够在代码中调整所有内容,如果可能的话,省略对模式图像的需求 .

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

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

不幸的是,他们都错过了目标,因为我想将渐变与自定义绘图结合起来 . 我希望CGGradient被我正在绘制的线框剪切(在圆角处可见),但我无法做到这一点 .

另一种方法是使用CAGradientLayer,它似乎工作得很好,但这需要在旋转时对帧进行一些调整,并且无论我如何尝试,渐变层似乎都会在文本的顶部绘制 .

我的问题是双重的

  • 如何修改下面的代码使渐变剪辑成为绘制"frame"

  • 如何让CAGradientLayer在UILabel的文本后面绘制(或者我必须将UIView放在UILabel后面,并以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];

1 回答

  • 3

    您正在寻找的是CGContextClip()

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

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

    (删除对CGContextDrawLinearGradient的旧调用)

    还要记住在进行任何裁剪之前和之后保存和恢复上下文

    如果您的剪辑与您想要的相反,请尝试CGContextEOClip()(或以相反的顺序绘制您的路径)

相关问题