iOS 5改变了内置Google Maps App绘制路线的方式:
我现在想在我自己的应用程序中复制路由叠加层的设计,但我目前只能绘制一条纯蓝色的线条.我想添加渐变,边框和辉光的3D效果.关于如何实现这一点的任何想法?
目前我正在使用以下代码:
- CGContextSetFillColorWithColor(context,fillColor.CGColor);
- CGContextSetLineJoin(context,kCGLineJoinRound);
- CGContextSetLineCap(context,kCGLineCapRound);
- CGContextSetLineWidth(context,lineWidth);
- CGContextAddPath(context,path);
- CGContextReplacePathWithStrokedPath(context);
- CGContextFillPath(context);
导致一个相当丑陋的行:
谢谢!
更新:该解决方案应该适用于iOS 4.0及以上版本.
解决方法
我认为@ChrisMiles是正确的,因为段可能是单独绘制. (我最初以为这可能是使用CGPatternRef可行的,但是您没有访问模式绘图回调中的CTM或路径端点.)
考虑到这一点,这里是一个非常粗糙的,背后的例子,说明你可能如何开始这样的努力(单独填写段落).注意:
>渐变颜色被猜到
>端盖不存在,需要单独实现
>还有一些混叠文物
>没有很大的注意力付出了表现
希望这可以让你开始至少(并通过一些分析几何).
- - (CGGradientRef)lineGradient
- {
- static CGGradientRef gradient = NULL;
- if (gradient == NULL) {
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGColorRef white = [[UIColor colorWithWhite:1.f
- alpha:0.7f] CGColor];
- CGColorRef blue = [[UIColor colorWithRed:0.1f
- green:0.2f
- blue:1.f
- alpha:0.7f] CGColor];
- CGColorRef lightBlue = [[UIColor colorWithRed:0.4f
- green:0.6f
- blue:1.f
- alpha:0.7f] CGColor];
- CFMutableArrayRef colors = CFArrayCreateMutable(kcfAllocatorDefault,8,NULL);
- CFArrayAppendValue(colors,blue);
- CFArrayAppendValue(colors,white);
- CFArrayAppendValue(colors,lightBlue);
- CFArrayAppendValue(colors,blue);
- CGFloat locations[8] = {0.f,0.08f,0.14f,0.21f,0.29f,0.86f,0.93f,1.f};
- gradient = CGGradientCreateWithColors(colorSpace,colors,locations);
- CFRelease(colors);
- CGColorSpaceRelease(colorSpace);
- }
- return gradient;
- }
- - (void)drawRect:(CGRect)rect
- {
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGContextSaveGState(context);
- CGContextSetAllowsAntialiasing(context,YES);
- CGContextSetShouldAntialias(context,YES);
- // Fill background color
- [[UIColor whiteColor] setFill];
- UIRectFill(rect);
- // Build a path
- CGFloat strokeWidth = 10.f;
- CGContextSetLineWidth(context,strokeWidth);
- CGGradientRef gradient = [self lineGradient];
- CGPoint points[9] = {
- CGPointMake(10.f,25.f),CGPointMake(100.f,100.f),150.f),CGPointMake(22.f,300.f),CGPointMake(230.f,400.f),200.f),CGPointMake(300.f,CGPointMake(310.f,160.f),CGPointMake(280.f,100.f)
- };
- for (NSUInteger i = 1; i < 9; i++) {
- CGPoint start = points[i - 1];
- CGPoint end = points[i];
- CGFloat dy = end.y - start.y;
- CGFloat dx = end.x - start.x;
- CGFloat xOffset,yOffset;
- // Remember that,unlike Cartesian geometry,origin is in *upper* left!
- if (dx == 0) {
- // Vertical to start,gradient is horizontal
- xOffset = 0.5 * strokeWidth;
- yOffset = 0.f;
- if (dy < 0) {
- xOffset *= -1;
- }
- }
- else if (dy == 0) {
- // Horizontal to start,gradient is vertical
- xOffset = 0.f;
- yOffset = 0.5 * strokeWidth;
- }
- else {
- // Sloped
- CGFloat gradientSlope = - dx / dy;
- xOffset = 0.5 * strokeWidth / sqrt(1 + gradientSlope * gradientSlope);
- yOffset = 0.5 * strokeWidth / sqrt(1 + 1 / (gradientSlope * gradientSlope));
- if (dx < 0 && dy > 0) {
- yOffset *= -1;
- }
- else if (dx > 0 && dy < 0) {
- xOffset *= -1;
- }
- else if (dx < 0 && dy < 0) {
- yOffset *= -1;
- xOffset *= -1;
- }
- else {
- }
- }
- CGAffineTransform startTransform = CGAffineTransformMakeTranslation(-xOffset,yOffset);
- CGAffineTransform endTransform = CGAffineTransformMakeTranslation(xOffset,-yOffset);
- CGPoint gradientStart = CGPointApplyAffineTransform(start,startTransform);
- CGPoint gradientEnd = CGPointApplyAffineTransform(start,endTransform);
- CGContextSaveGState(context);
- CGContextMoveToPoint(context,start.x,start.y);
- CGContextAddLineToPoint(context,end.x,end.y);
- CGContextReplacePathWithStrokedPath(context);
- CGContextClip(context);
- CGContextDrawLinearGradient(context,gradient,gradientStart,gradientEnd,kCGGradientDrawsAfterEndLocation | kCGGradientDrawsBeforeStartLocation);
- CGContextRestoreGState(context);
- }
- CGContextRestoreGState(context);
- }