2

我正在尝试 在 iOS 上使用 UIKit 或 CoreGraphics重新创建类似这种形状的东西 - http://www.creativeapplications.net/wp-content/uploads/2010/09/horizo ​​n_02_1024x768.png。

图片中的那个是用 openFrameworks 完成的,它确实在 iOS 上运行。但是,我想在不必使用 oF 的情况下构建相同的内容,因此我可以将其全部保留为原生。

我假设形状是通过 Delaunay 三角剖分创建的,我可以在 Objective-C 中做到这一点。问题是用渐变而不是普通的 UIColor 填充形状!

有没有一种方法可以在 iPad 上以良好的性能本地完成这样的事情,还是我应该使用 openFrameworks 来完成并将其作为一个层引入应用程序?

4

2 回答 2

2

你问如何用渐变填充三角形?下面的代码就是这样做的。要让它工作,你需要添加 QuartzCore 框架,并且

#import <QuartzCore/QuartzCore.h>

该代码创建了一个三角形形状的图层,然后将其用作渐变图层的蒙版。希望这可以帮助。

- (void)drawRect:(CGRect)rect
{
    CGFloat w = self.bounds.size.width / 4;
    CGFloat h = self.bounds.size.height / 4;
    CGFloat x = w * 2;
    CGFloat y = h;
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path,NULL, x, y);
    CGPathAddLineToPoint(path, NULL, x+w, y+2*h);
    CGPathAddLineToPoint(path, NULL, x-w, y+2*h);
    CGPathCloseSubpath(path);


    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
    [shapeLayer setPath:path];

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
    gradientLayer.startPoint = CGPointMake(0.25, 1.0);
    gradientLayer.endPoint = CGPointMake(0.75, 0.0);
    UIColor *startColour = [UIColor redColor];
    UIColor *endColour = [UIColor greenColor];
    gradientLayer.colors = [NSArray arrayWithObjects:(id)[startColour CGColor], (id)[endColour CGColor], nil];

    [gradientLayer setMask:shapeLayer];

    [self.layer addSublayer:gradientLayer];

    CGPathRelease(path);
}
于 2013-06-18T01:31:46.920 回答
1

我将做一个三角形,但你可以使用重复做多个:

//Create the triangle Path and clip the drawing to it
CGContextSaveGState(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, self.bounds.size.width * .4, self.bounds.size.height * 1/6.);
CGContextAddLineToPoint(context,self.bounds.size.width * .4, self.bounds.size.height * 3/6.);
CGContextAddLineToPoint(context,self.bounds.size.width * .2, self.bounds.size.height * 3/6.);
CGContextClosePath(context);
CGContextClip(context);

//Now call the linear gradient drawing function
[self drawLinearGradient:context withRect:self.bounds startColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:.3] endColor:[UIColor colorWithRed:.5 green:.5 blue:.5 alpha:.3] startFraction:.3 stopFraction:1];

//And now restore so that we can clip the next triangle
CGContextRestoreGState(context);

现在为线性渐变绘制代码:

- (void) drawLinearGradient: (CGContextRef) context withRect: (CGRect) rect startColor: (UIColor*) startColor endColor: (UIColor*)  endColor startFraction:(float)start stopFraction:(float)stop
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat locations[] = { start, stop };

    CGGradientRef myGradient;
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

    CGColorRef startColorRef = [startColor CGColor];
    CGColorRef endColorRef = [endColor CGColor];

    const CGFloat *components = CGColorGetComponents(startColorRef);
    CGFloat red     = components[0];
    CGFloat green = components[1];
    CGFloat blue   = components[2];
    CGFloat alpha = components[3];

    const CGFloat *components2 = CGColorGetComponents(endColorRef);
    CGFloat red2     = components2[0];
    CGFloat green2 = components2[1];
    CGFloat blue2   = components2[2];
    CGFloat alpha2 = components2[3];

    CGFloat colors[] =
    {
        red, green, blue, alpha,
        red2, green2, blue2, alpha2
    };

    myGradient = CGGradientCreateWithColorComponents(rgb, colors, locations, 2);
    CGColorSpaceRelease(rgb);

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

    CGContextSaveGState(context);
    CGContextAddRect(context, rect);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, myGradient, startPoint, endPoint, 0);
    CGContextRestoreGState(context);

    CGGradientRelease(myGradient);
    CGColorSpaceRelease(colorSpace);
}

如果你愿意,你可以设置这个线性渐变函数来处理两个以上的位置/颜色。这是非常基本的,但是如果您知道每个三角形的开始和停止颜色以及位置,您应该能够使用此代码(无需数百个子层)完成您想要的(本机绘图)。虽然图层可能绘制得更快,但我不知道。

于 2013-06-18T15:48:39.217 回答