CoreGraphics矩形渐变

时间:2013-09-20 13:45:39

标签: ios core-graphics linear-gradients

有人可以帮我用CoreGraphics绘制一个特定的渐变吗? 只是提供线索就足够了。 示例代码应该得到我最深的尊重。 我需要这个形状:

enter image description here

我尝试了以下代码:

-(UIImage *)imageWithGradientBorder
{
    CGRect rect=CGRectMake(0, 0, self.size.width, self.size.height);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef ctx= CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, rect.size.width, colorSpace, kCGImageAlphaNone);
    CGGradientRef glossGradient;
    size_t num_locations = 4;
    CGFloat locations[4] = { 0.0, 0.1, 0.9, 1.0 };
    CGFloat components[16] = { 0, 0, 0, 1, 1.0, 1.0, 1.0, 1, 1.0, 1.0, 1.0, 1, 0, 0, 0, 1};
    glossGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, num_locations);
    CGRect currentBounds = rect;

    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
    topCenter = CGPointMake( 0.0f, CGRectGetMidY(currentBounds));
    midCenter = CGPointMake(CGRectGetMaxX(currentBounds), CGRectGetMidY(currentBounds));

    CGContextDrawLinearGradient(ctx, glossGradient, topCenter, midCenter, 0);
    CGImageRef mask = CGBitmapContextCreateImage(ctx);
    CGContextRelease(ctx);
    CGImageRef maskedImageRef = CGImageCreateWithMask([self CGImage], mask);
    CGImageRelease(mask);
    UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
    CGImageRelease(maskedImageRef);
    return maskedImage;
}

但它只从左侧绘制渐变。

4 个答案:

答案 0 :(得分:1)

topCenter = CGPointMake( 0.0f, CGRectGetMidY(currentBounds));
midCenter = CGPointMake(CGRectGetMaxX(currentBounds), CGRectGetMidY(currentBounds));

这两个变量有误导性的名称,它们不是真正的中心和中间中间,它们是中左和右中。所以当你打电话时:

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

您正在从左向右绘制渐变。

您需要做什么来组织您的点并绘制梯度4次(L-> R,R-> L,T-> B,B-> T)。根据您想要的角落看起来准确,您可能需要在每个渐变绘图之间进行一些遮罩,以防止渐变一直画到角落。

答案 1 :(得分:0)

好的,我已经制作了一个解决方法。

CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextRef context = currentContext;
CGContextSaveGState(currentContext);
CGFloat colStep = 255 / borderWidth / 10;
colStep = colStep / 255;
for (int i = 0; i < floor(borderWidth * 10); i++) {
    CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:colStep*i alpha:1].CGColor);
    CGFloat delta = i / 10;
    CGRect rectToDraw = CGRectMake(delta,delta,rect.size.width - delta * 2,rect.size.height - delta * 2);
    CGContextFillRect(context, rectToDraw);
}


CGContextRestoreGState(currentContext);

答案 2 :(得分:0)

对于原始问题,其他答案更好,但如果您不需要使用CoreGraphics进行绘制,则可能需要考虑使用资产目录进行图像切片。您可以在图形程序中创建渐变和角点,并使其在Xcode中可调整大小。 https://developer.apple.com/library/ios/recipes/xcode_help-image_catalog-1.0/chapters/SlicinganImage.html

答案 3 :(得分:0)

class BorderView: UIView {
    private var lineHeight: CGFloat = 80
    var colors: [UIColor] = [UIColor.black, UIColor.white]
    {
        didSet {
            setNeedsDisplay()
        }
    }
    override func draw(_ rect: CGRect) {

        let line1 = _getLineLayer()
    layer.addSublayer(line1)

        let line2 = _getLineLayer()
    let t = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -rect.maxY + lineHeight)
        line2.setAffineTransform(t)
        layer.addSublayer(line2)

        let line3 = _getLineLayer()
        let t1 = CGAffineTransform(rotationAngle:     CGFloat(M_PI_2)).translatedBy(x: rect.midX - lineHeight/2, y: -rect.midY + lineHeight/2)
        line3.setAffineTransform(t1)
        layer.addSublayer(line3)

        let line4 = _getLineLayer()
        let t2 = CGAffineTransform(rotationAngle: -(CGFloat)(M_PI_2)).translatedBy(x: -rect.midX + lineHeight/2, y: -rect.midY + lineHeight/2)
        line4.setAffineTransform(t2)
        layer.addSublayer(line4)


    }

    private func _getLineLayer() -> CALayer {

        let gl = CAGradientLayer()
        gl.frame = CGRect(x: 0, y: 0, width: layer.bounds.width, height: lineHeight)
        gl.colors = colors.map({$0.cgColor})

        // Get mask layer
        let p1 = CGPoint.zero
        let p2 = CGPoint(x: layer.bounds.width, y: 0)
        let p3 = CGPoint(x: layer.bounds.width - lineHeight, y: lineHeight)
        let p4 = CGPoint(x: lineHeight, y: lineHeight)

        let path = UIBezierPath()
        path.move(to: p1)
        path.addLine(to: p2)
        path.addLine(to: p3)
        path.addLine(to: p4)
        path.close()
        let shapeLayer = CAShapeLayer()
        shapeLayer.frame = gl.frame
        shapeLayer.path = path.cgPath
        gl.mask = shapeLayer
        return gl
    }
}

Usage

let frame = CGRect(x: 0, y: 0, width: 500, height: 500)
let view = BorderView(frame: frame)
view.backgroundColor = .white
PlaygroundPage.current.liveView = view
view.colors = [.black, .white]
中的RouterLink

Output view