gpt4 book ai didi

iphone - 使用核心图形绘制浮雕弧

转载 作者:可可西里 更新时间:2023-11-01 03:04:15 25 4
gpt4 key购买 nike

我正在尝试实现一个自定义 slider ,如下图所示。

enter image description here

到目前为止我所做的看起来像这样

enter image description here

请帮我画出这样效果的圆弧。我的代码如下,我正在做的是使用线宽为 kLineWidth 的 CGContextAddArc 绘制圆弧。

- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext: (CGContextRef)context {
UIGraphicsPushContext(context);
CGContextBeginPath(context);

CGContextMoveToPoint(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y);

CGImageRef imageRef = [UIImage imageNamed:@"circle25.png"].CGImage;
CGRect rect = CGRectMake(sliderButtonCenterPoint.x - kThumbRadius, sliderButtonCenterPoint.y - kThumbRadius, kThumbRadius*2, kThumbRadius*2);
CGContextDrawImage(context, rect, imageRef);

//CGContextAddArc(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y, kThumbRadius, 0.0, 2*M_PI, NO);

CGContextFillPath(context);
UIGraphicsPopContext();
}

- (CGPoint)drawArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius inContext:(CGContextRef)context {
UIGraphicsPushContext(context);
CGContextBeginPath(context);

float angleFromTrack = translateValueFromSourceIntervalToDestinationInterval(track, self.minimumValue, self.maximumValue, 0, M_PI/3);// 2*M_PI

CGFloat startAngle = (4*M_PI)/3;
CGFloat endAngle = startAngle + angleFromTrack;

CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, NO);

CGPoint arcEndPoint = CGContextGetPathCurrentPoint(context);

CGContextStrokePath(context);

UIGraphicsPopContext();

return arcEndPoint;
}

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();

CGPoint middlePoint;
middlePoint.x = self.bounds.origin.x + self.bounds.size.width/2;
middlePoint.y = self.bounds.origin.y + self.bounds.size.width;

CGContextSetLineWidth(context, kLineWidth);

CGFloat radius = [self sliderRadius];


[self.maximumTrackTintColor setStroke];
[self drawArcTrack:self.maximumValue atPoint:middlePoint withRadius:radius inContext:context];
[self.minimumTrackTintColor setStroke];
self.thumbCenterPoint = [self drawArcTrack:self.value atPoint:middlePoint withRadius:radius inContext:context];

[self.thumbTintColor setFill];
[self drawThumbAtPoint:self.thumbCenterPoint inContext:context];
}

最佳答案

除非您要动态更改形状,否则最好只在图像编辑器中创建图像。我知道在 Photoshop、Illustrator 或 Fireworks 中创建这种效果很容易。

也就是说,使用 Core Graphics 绘制这样的内部阴影需要几个步骤:

  1. 剪辑到形状(使用例如 CGContextClipCGContextClipToMask)。
  2. 形状以外的所有东西制作路径或 mask 。
  3. 设置阴影参数(使用 CGContextSetShadowWithColor)。
  4. 填充步骤 2 中的路径或蒙版。这会在形状内部转换阴影,并且只绘制阴影,因为您在步骤 1 中剪裁到形状。

如果你做对了所有这些,你会得到这样一个不错的结果:

screen shot of arc with inner shadow

这是我为绘制它而编写的代码。我在自定义 View 子类的 drawRect: 中编写了它,但您可以轻松地使用此代码绘制到任何图形上下文中。

- (void)drawRect:(CGRect)rect {
CGContextRef gc = UIGraphicsGetCurrentContext();

首先,我创建了一条弧形路径:

    static CGFloat const kArcThickness = 20.0f;
CGRect arcBounds = CGRectInset(self.bounds, 10.0f, 10.0f);
CGPoint arcCenter = CGPointMake(CGRectGetMidX(arcBounds), CGRectGetMidY(arcBounds));
CGFloat arcRadius = 0.5f * (MIN(arcBounds.size.width, arcBounds.size.height) - kArcThickness);
UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:-M_PI / 3.0 endAngle:-2.0 * M_PI / 3.0 clockwise:NO];

接下来,我要求 Core Graphics 创建一条新路径,即 arc 路径的轮廓。请注意我如何要求它的笔画宽度为 kArcThickness 和圆线帽:

    CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f);

我还需要该路径的逆:包含shape 中的点的所有点的路径。 CGContextCreateCopyByStrokingPathCGPathAddRect 绘制方向相反(尽管我认为没有记录)就这样发生了。因此,如果我复制 shape 并在其周围画一个巨大的矩形,非零缠绕规则意味着新路径将是 shape 的倒数:

    CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape);
CGPathAddRect(shapeInverse, NULL, CGRectInfinite);

现在我真的可以开始画画了。首先,我将用浅灰色填充形状:

    CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor);
CGContextFillPath(gc);

接下来我实际执行上面列出的四个步骤。我必须保存图形状态,以便在完成后撤消剪裁和阴影参数。

    CGContextSaveGState(gc); {

第 1 步:剪裁形状:

        CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextClip(gc);

第 2 步:嗯,我在创建 shapeInverse 时已经执行了这一步。

第 3 步:设置阴影参数:

        CGContextSetShadowWithColor(gc, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor);

第 4 步:我填充第 2 步中的反向形状:

        CGContextBeginPath(gc);
CGContextAddPath(gc, shapeInverse);
CGContextFillPath(gc);

现在我恢复图形状态,具体恢复剪切路径并取消设置阴影参数。

    } CGContextRestoreGState(gc);

最后,我将用浅灰色描边 shape 以使边缘更清晰:

    CGContextSetStrokeColorWithColor(gc, [UIColor colorWithWhite:.75 alpha:1].CGColor);
CGContextSetLineWidth(gc, 1);
CGContextSetLineJoin(gc, kCGLineCapRound);
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextStrokePath(gc);

我当然会在完成后进行清理:

    CGPathRelease(shape);
CGPathRelease(shapeInverse);
}

更复杂的形状可以看my answer heremy answer here .

为了方便复制,这里把所有的代码放在一起:

- (void)drawRect:(CGRect)rect {
CGContextRef gc = UIGraphicsGetCurrentContext();

static CGFloat const kArcThickness = 20.0f;
CGRect arcBounds = CGRectInset(self.bounds, 10.0f, 10.0f);
CGPoint arcCenter = CGPointMake(CGRectGetMidX(arcBounds), CGRectGetMidY(arcBounds));
CGFloat arcRadius = 0.5f * (MIN(arcBounds.size.width, arcBounds.size.height) - kArcThickness);
UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:-M_PI / 3.0 endAngle:-2.0 * M_PI / 3.0 clockwise:NO];
CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f);
CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape);
CGPathAddRect(shapeInverse, NULL, CGRectInfinite);

CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor);
CGContextFillPath(gc);

CGContextSaveGState(gc); {
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextClip(gc);
CGContextSetShadowWithColor(gc, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor);
CGContextBeginPath(gc);
CGContextAddPath(gc, shapeInverse);
CGContextFillPath(gc);
} CGContextRestoreGState(gc);

CGContextSetStrokeColorWithColor(gc, [UIColor colorWithWhite:.75 alpha:1].CGColor);
CGContextSetLineWidth(gc, 1);
CGContextSetLineJoin(gc, kCGLineCapRound);
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextStrokePath(gc);

CGPathRelease(shape);
CGPathRelease(shapeInverse);
}

关于iphone - 使用核心图形绘制浮雕弧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10417982/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com