UIView 用虚线边框绘制圆圈 [英] UIView Draw Circle with Dotted Line Border

查看:88
本文介绍了UIView 用虚线边框绘制圆圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法画一个带虚线边框的 UIView 圆?我想控制点之间的间距和点的大小.我试着指定我自己的图案图像,但是当我把它做成一个圆圈时,它看起来不太好:

UIView *mainCircle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];[mainCircle.layer setCornerRadius:100];[mainCircle.layer setBorderWidth:5.0];[mainCircle.layer setBorderColor:[[UIColor colorWithPatternImage:[UIImage imageNamed:@"dotted"]] CGColor]];[self.view addSubview:mainCircle];[mainCircle setCenter:self.view.center];

解决方案

请注意在顶部如何重叠点.这是因为圆的周长不能完全被点数整除.

您可以通过之前进行一些简单的数学运算来相对轻松地解决此问题.我编写了几行代码,可以让您提供点直径值以及预期的点间距 - 它会尝试近似最接近的点间距,从而得到整数个点.

此外,我建议您采用 100% 分层的方法,使用 CAShapeLayer 绘制圆.这样您就可以轻松地为其添加动画,而无需为每一帧完全重新绘制.

这样的事情应该可以解决问题:

//您的网点直径.CGFloat dotDiameter = 10.0;//您的预期"点间距.我们将尝试尽可能接近此值.CGFloat expDotSpacing = 20.0;//视图的大小CGSize s = self.view.frame.size;//圆的半径,宽度或高度的一半(以较小者为准)减去点半径以考虑描边CGFloat 半径 = (s.width 

您现在将获得以下输出:

如果您想在 UIView 中使用它,我建议将其子类化并添加 CAShapeLayer 作为子层.您还需要添加一个遮罩层,以便将视图的内容遮罩到边框内.

我在下面的完整项目中添加了一个示例.

<小时>

完整项目:https://github.com/hamishknight/Dotted-Circle-查看

Is there a way to draw a UIView circle with a dotted line border? I want to have control over the spacing between the dots, and the size of the dots. I tried specifying my own pattern image, but when I make it into a circle it doesn't look good:

UIView *mainCircle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[mainCircle.layer setCornerRadius:100];
[mainCircle.layer setBorderWidth:5.0];
[mainCircle.layer setBorderColor:[[UIColor colorWithPatternImage:[UIImage imageNamed:@"dotted"]] CGColor]];
[self.view addSubview:mainCircle];
[mainCircle setCenter:self.view.center];

解决方案

Following on from aksh1t's answer and rob's answer, you should use a round line cap, along with a dash pattern to do this.

The only thing I would add is that with the current code, you can end up with results like this:

Notice how at the top, you get an overlap of the dots. This is due to the fact that the circumference of the circle isn't entirely divisible by the number of dots.

You can fix this relatively easily by doing a simple bit of maths before. I wrote a few lines of code that'll allows you to provide an dot diameter value, along with an expected dot spacing - and it will try and approximate the nearest dot spacing that will result in an integral number of dots.

Also, I recommend you take an 100% layered approach, using CAShapeLayer to draw your circle. That way you can easily add animations to it without having to completely re-draw it for each frame.

Something like this should do the trick:

// your dot diameter.
CGFloat dotDiameter = 10.0;

// your 'expected' dot spacing. we'll try to get as closer value to this as possible.
CGFloat expDotSpacing = 20.0;

// the size of your view
CGSize s = self.view.frame.size;

// the radius of your circle, half the width or height (whichever is smaller) with the dot radius subtracted to account for stroking
CGFloat radius = (s.width < s.height) ? s.width*0.5-dotDiameter*0.5 : s.height*0.5-dotDiameter*0.5;

// the circumference of your circle
CGFloat circum = M_PI*radius*2.0;

// the number of dots to draw as given by the circumference divided by the diameter of the dot plus the expected dot spacing.
NSUInteger numberOfDots = round(circum/(dotDiameter+expDotSpacing));

// the calculated dot spacing, as given by the circumference divided by the number of dots, minus the dot diameter.
CGFloat dotSpacing = (circum/numberOfDots)-dotDiameter;

// your shape layer
CAShapeLayer* l = [CAShapeLayer layer];
l.frame = (CGRect){0, 0, s.width, s.height};

// set to the diameter of each dot
l.lineWidth = dotDiameter;

// your stroke color
l.strokeColor = [UIColor blackColor].CGColor;

// the circle path - given the center of the layer as the center and starting at the top of the arc.
UIBezierPath* p = [UIBezierPath bezierPathWithArcCenter:(CGPoint){s.width*0.5, s.height*0.5} radius:radius startAngle:-M_PI*0.5 endAngle:M_PI*1.5 clockwise:YES];
l.path = p.CGPath;

// prevent that layer from filling the area that the path occupies
l.fillColor = [UIColor clearColor].CGColor;

// round shape for your stroke
l.lineCap = kCALineCapRound;

// 0 length for the filled segment (radius calculated from the line width), dot diameter plus the dot spacing for the un-filled section
l.lineDashPattern = @[@(0), @(dotSpacing+dotDiameter)];

[self.view.layer addSublayer:l];

You'll now get the following output:

If you want to use this in a UIView, I would suggest subclassing it and adding the CAShapeLayer as a sublayer. You'll also want to add a masking layer in order to mask the view's contents to inside the border.

I have added an example of this in the full project below.


Full Project: https://github.com/hamishknight/Dotted-Circle-View

这篇关于UIView 用虚线边框绘制圆圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆