【问题标题】:UIBezierPath and gradient iOSUIBezierPath 和渐变 iOS
【发布时间】:2013-08-20 07:34:26
【问题描述】:

我有带值的路径,我想制作这个渐变。

代码如下:

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:171.0/255.0 alpha:0.6] CGColor]);
    CGContextSetFillColorWithColor(context, [[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:171.0/255.0 alpha:0.6] CGColor]);



    UIBezierPath *aPath = [UIBezierPath bezierPath];
    [aPath moveToPoint:CGPointMake(30.0, 100.0)];


    [aPath addLineToPoint:CGPointMake(200.0, 120.0)];
    [aPath addLineToPoint:CGPointMake(300, 210)];
    [aPath addLineToPoint:CGPointMake(300, 420)];
    [aPath addLineToPoint:CGPointMake(30, 420.0)];
    [aPath addLineToPoint:CGPointMake(30, 100.0)];

    [aPath closePath];
    [aPath fill];

有任何指针可以找出这段代码的问题吗?

【问题讨论】:

    标签: ios gradient uibezierpath


    【解决方案1】:

    首先 - 我用贝塞尔路径创建了简单的箭头:

    UIBezierPath* bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint: CGPointMake(24.5, 1.5)];
    [bezierPath addLineToPoint: CGPointMake(2.5, 14.5)];
    [bezierPath addLineToPoint: CGPointMake(24.5, 28.5)];
    [bezierPath addLineToPoint: CGPointMake(24.5, 1.5)];
    [bezierPath closePath];
    [[UIColor blackColor] setStroke];
    bezierPath.lineWidth = 1;
    [bezierPath stroke];
    

    然后我绘制了从黑到白的简单线性渐变:

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    NSArray* simpleLinearGradientColors = [NSArray arrayWithObjects:
                                           (id)[UIColor blackColor].CGColor,
                                           (id)[UIColor whiteColor].CGColor, nil];
    CGFloat simpleLinearGradientLocations[] = {0, 1};
    CGGradientRef simpleLinearGradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)simpleLinearGradientColors, simpleLinearGradientLocations);
    
    
    // Bezier Drawing
    UIBezierPath* bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint: CGPointMake(24.5, 1.5)];
    [bezierPath addLineToPoint: CGPointMake(2.5, 14.5)];
    [bezierPath addLineToPoint: CGPointMake(24.5, 28.5)];
    [bezierPath addLineToPoint: CGPointMake(24.5, 1.5)];
    [bezierPath closePath];
    CGContextSaveGState(context);
    [bezierPath addClip];
    CGContextDrawLinearGradient(context, simpleLinearGradient, CGPointMake(2.5, 15), CGPointMake(24.5, 15), 0);
    CGContextRestoreGState(context);
    
    [[UIColor blackColor] setStroke];
    bezierPath.lineWidth = 1;
    [bezierPath stroke];
    
    CGGradientRelease(simpleLinearGradient);
    CGColorSpaceRelease(colorSpace);
    

    这就是我得到的:

    基本上,您可以使用一系列设置(位置、颜色)创建线性、径向渐变,当然您应该修改上面的代码。

    【讨论】:

    • 当然你应该通过设置适当的值来修改代码
    • 如何给aPath添加渐变?
    • 你不能将它添加到路径中!它是在相同的上下文中绘制的
    • 我做这个:CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations);但在这里我无法绘制外部渐变。但在这里我不能画外渐变; CGContextSaveGState(上下文); [aPath 填充]; [aPath addClip]; CGContextDrawLinearGradient(context, 渐变, CGPointMake(10, 10), CGPointMake(320, 10), 0); CGColorSpaceRelease(colorSpace); CGGradientRelease(梯度);
    • 但在这种情况下我无法绘制外部渐变。
    【解决方案2】:

    1.为 CustomGradientView 创建 .h 和 .m 文件

    1. CustomGradientView.h 文件应如下所示

      @interface CustomGradientView : UIView

    CustomGradientView.m 文件应如下所示 - (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    // color1 and color 2 u can take as u wish here i m taking for explaining
    UIColor *color1=[UIColor whiteColor];
    CGColorRef startColor =color1.CGColor;
    
    UIColor *color2=[UIColor redColor];
    CGColorRef endColor = color2.CGColor;
    
    drawLinearGradient(context, rect, startColor, endColor);
    
    //for rounded corners
    CGPathRef p = [[UIBezierPath bezierPathWithRoundedRect:rect
                                              5] CGPath];
    CGContextAddRect(context, rect);
    CGContextAddPath(context, p);
    CGContextEOClip(context);
    CGContextClearRect(context, rect);
    

    }

    然后在 .xib 文件中你想要渐变的视图扩展它的类 CustomGradientView 而不是 UIView

    drawLinearGradient 方法在另一个类中,你必须导入它 他们是

    Common.h

    #import <Foundation/Foundation.h>
    void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef  endColor);
    CGRect rectFor1PxStroke(CGRect rect);
    void draw1PxStroke(CGContextRef context, CGPoint startPoint, CGPoint endPoint, CGColorRef color);
    void drawGlossAndGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor);
    static inline double radians (double degrees) { return degrees * M_PI/180; }
    CGMutablePathRef createArcPathFromBottomOfRect(CGRect rect, CGFloat arcHeight);
    CGMutablePathRef createRoundedRectForRect(CGRect rect, CGFloat radius);
    

    和 Common.m

    #import "Common.h"
    
    CGRect rectFor1PxStroke(CGRect rect) {
        return CGRectMake(rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height - 1);
    }
    
    void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef  endColor) {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGFloat locations[] = { 0.0, 1.0 };
    
        NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
    
        CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
    
        CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
        CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
    
        CGContextSaveGState(context);
        CGContextAddRect(context, rect);
        CGContextClip(context);
        CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
        CGContextRestoreGState(context);
    
        CGGradientRelease(gradient);
    }
    
    void draw1PxStroke(CGContextRef context, CGPoint startPoint, CGPoint endPoint, CGColorRef color) {
    
        CGContextSaveGState(context);
        CGContextSetLineCap(context, kCGLineCapSquare);
        CGContextSetStrokeColorWithColor(context, color);
        CGContextSetLineWidth(context, 1.0);
        CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5);
        CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5);
        CGContextStrokePath(context);
        CGContextRestoreGState(context);        
    
    }
    
    void drawGlossAndGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor) {
    
        drawLinearGradient(context, rect, startColor, endColor);
    
        CGColorRef glossColor1 = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.35].CGColor;
        CGColorRef glossColor2 = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.1].CGColor;
    
        CGRect topHalf = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height/2);
    
        drawLinearGradient(context, topHalf, glossColor1, glossColor2);
    
    }
    
    CGMutablePathRef createArcPathFromBottomOfRect(CGRect rect, CGFloat arcHeight) {
    
        CGRect arcRect = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height - arcHeight, 
                                    rect.size.width, arcHeight);
    
        CGFloat arcRadius = (arcRect.size.height/2) + (pow(arcRect.size.width, 2) / (8*arcRect.size.height));
        CGPoint arcCenter = CGPointMake(arcRect.origin.x + arcRect.size.width/2, arcRect.origin.y + arcRadius);
    
        CGFloat angle = acos(arcRect.size.width / (2*arcRadius));
        CGFloat startAngle = radians(180) + angle;
        CGFloat endAngle = radians(360) - angle;
    
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddArc(path, NULL, arcCenter.x, arcCenter.y, arcRadius, startAngle, endAngle, 0);
        CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect));
        CGPathAddLineToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect));
        CGPathAddLineToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect));
        return path;    
    
    }
    
    CGMutablePathRef createRoundedRectForRect(CGRect rect, CGFloat radius) {
    

    【讨论】:

    • drawLinearGradient 方法在哪里?
    • 抱歉一半的答案。我已经发布了完整的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多