ios – 使用ObjectiveC的核心图形,如何围绕圆圈弯曲箭头?

ios – 使用ObjectiveC的核心图形,如何围绕圆圈弯曲箭头?,第1张

概述我们的设计师让我重新创建: 我是UIView的子类,我已经覆盖了drawRect命令,如下所示: [super drawRect:frame];CGFloat x = self.frame.origin.x;CGFloat y = self.frame.origin.y;CGFloat w = self.frame.size.width;CGFloat h = self.frame.si 我们的设计师让我重新创建:

我是UIVIEw的子类,我已经覆盖了drawRect命令,如下所示:

[super drawRect:frame];CGfloat x = self.frame.origin.x;CGfloat y = self.frame.origin.y;CGfloat w = self.frame.size.wIDth;CGfloat h = self.frame.size.height;CGfloat linewidth = linewidthRequested;CGPoint centerPoint = CGPointMake(w/2,h/2);CGfloat radius = radiusRequested;CGfloat startAngle = 3 * M_PI / 2;CGfloat endAngle = startAngle + percentage * 2 * M_PI;CGMutablePathref arc = CGPathCreateMutable();CGPathAddArc(arc,NulL,centerPoint.x,centerPoint.y,radius,startAngle,endAngle,NO);CGPathref strokedArc = CGPathCreatecopyByStrokingPath(arc,linewidth,kCGlineCapButt,kCGlineJoinMiter,// the default                               10); // 10 is default miter limitCGContextRef c = UIGraphicsGetCurrentContext();CGContextAddpath(c,strokedArc);CGContextSetFillcolorWithcolor(c,[UIcolor colorWithRed:239/255.0 green:101/255.0 blue:47/255.0 Alpha:1.0].CGcolor);CGContextDrawPath(c,kCGPathFill);

我最终得到的是:

还得画箭头.会很容易,对吧?

在努力记住我的触发后,我在这个页面的中心周围找到了旋转点:
Rotating a point around an origin in VB

但是当我尝试翻译到目标C来绘制箭头时,我得到了非常奇怪的结果.这是drawRect中的代码:

CGfloat triangle[3][2] = {{centerPoint.x + 10,h - (centerPoint.y + radius)},{centerPoint.x,h - (centerPoint.y + radius + linewidth/2)},h - (centerPoint.y + radius - linewidth/2)}};for (int IDx=0;IDx < 3; IDx++) {    // translate to origin    triangle[IDx][0] -= centerPoint.x;    triangle[IDx][1] -= centerPoint.y;}CGfloat angdistance = endAngle - startAngle;CGfloat ct = cos(angdistance);CGfloat st = sin(angdistance);for (int IDx=0;IDx < 3; IDx++) {    // rotate    triangle[IDx][0] = ct * triangle[IDx][0] - st * triangle[IDx][1];    triangle[IDx][1] = -st * triangle[IDx][0] + ct * triangle[IDx][1];}for (int IDx=0;IDx < 3; IDx++) {    // translate back to position    triangle[IDx][0] += centerPoint.x;    triangle[IDx][1] += centerPoint.y;}NSLog(@"Rotating through %g,%06.1f,ct - %g,st - %g",angdistance,triangle[0][0],triangle[0][1],ct,st);// XXX todo draw the filled triangle at end.// draw a red triangle,the point of the arrowCGContextSetFillcolorWithcolor(c,[[UIcolor greencolor] CGcolor]);CGContextMovetoPoint(c,triangle[0][1]);CGContextAddlinetoPoint(c,triangle[1][0],triangle[1][1]);CGContextAddlinetoPoint(c,triangle[2][0],triangle[2][1]);CGContextFillPath(c);

我期待我制作这些点,然后将它们翻译成原点,旋转,然后将它们翻译回来,我会笑.

然而,这并不是正在发生的事情……当百分比从0增加到2pi时,箭头会在一个模糊的三角形路线中自行绘制.当angdistance为零或pi时,箭头位于正确的位置.当我朝向pi / 2或3pi / 2时,箭头朝向封闭矩形的下角移开.

我必须做一些明显愚蠢的事情,但我不能为我的生活看到它.

有任何想法吗?

谢谢,

-Ken

解决方法 我建议为所需形状的整个轮廓构建一条路径,然后用所需的颜色“填充”该路径.这消除了任何间隙或任何不完整排队的风险.

因此,该路径可能包括箭头外部的弧,箭头的两条线,箭头内部的弧形,然后关闭路径.这可能看起来像:

- (voID)drawRect:(CGRect)rect {    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextSetFillcolorWithcolor(context,self.arrowcolor.CGcolor);    CGPoint center = CGPointMake(rect.size.wIDth / 2.0,rect.size.height / 2.0);    CGContextMovetoPoint(context,center.x + cosf(self.startAngle) * (self.radius + self.linewidth / 2.0),center.y + sinf(self.startAngle) * (self.radius + self.linewidth / 2.0));    CGContextAddArc(context,center.x,center.y,self.radius + self.linewidth / 2.0,self.startAngle,self.endAngle,!self.clockwise);    CGfloat theta = asinf(self.linewidth / self.radius / 2.0) * (self.clockwise ? 1.0 : -1.0);    CGfloat pointdistance = self.radius / cosf(theta);    CGContextAddlinetoPoint(context,center.x + cosf(self.endAngle + theta) * pointdistance,center.y + sinf(self.endAngle + theta) * pointdistance);    CGContextAddlinetoPoint(context,center.x + cosf(self.endAngle) * (self.radius - self.linewidth / 2.0),center.y + sinf(self.endAngle) * (self.radius - self.linewidth / 2.0));    CGContextAddArc(context,self.radius - self.linewidth / 2.0,self.clockwise);    CGContextClosePath(context);    CGContextDrawPath(context,kCGPathFill);}

这里唯一的技巧就是为箭头结束提出正确的观点.我已经改进了更好地处理更胖箭头的选择,但是您应该随意使用您认为最适合您应用的任何东西.

因此,以下代码:

self.arrowVIEw.radius = 100;self.arrowVIEw.arrowcolor = [UIcolor bluecolor];self.arrowVIEw.linewidth = 40;self.arrowVIEw.startAngle = -M_PI_2;self.arrowVIEw.endAngle = M_PI;self.arrowVIEw.clockwise = TRUE;

会得到以下(我使用CAdisplay@R_301_6862@制作动画):

这使用零起​​始角作为“3点钟”位置,但你可以在你认为合适时调整它.但希望它说明了解决问题的一种方法.

顺便说一句,虽然我已经回答了如何使用CoreGraphics这样做的问题,但我不一定建议这样做.例如,在https://github.com/robertmryan/CircularArrowDemo中,我没有实现drawRect,而是更新CAShapeLayer.通过这样做,我不仅可以避免drawRect效率低下,而且理论上也可以改变你使用这个CAShapeLayer的方式(例如,将它用作某些UIVIEw的掩码,在其后面显示一些更有趣的颜色渐变(或其他图像)).

总结

以上是内存溢出为你收集整理的ios – 使用ObjectiveC的核心图形,如何围绕圆圈弯曲箭头?全部内容,希望文章能够帮你解决ios – 使用ObjectiveC的核心图形,如何围绕圆圈弯曲箭头?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1070128.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存