UIView绘制圆圈与虚线边框

时间:2016-03-12 18:46:56

标签: ios objective-c 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];

enter image description here

2 个答案:

答案 0 :(得分:8)

继续aksh1t's answerrob's answer后,您应该使用圆形线帽以及破折号模式来执行此操作。

我唯一要补充的是,使用当前代码,您最终可以获得如下结果:

enter image description here

请注意,在顶部,您会得到点的重叠。这是因为圆的圆周不能完全被点数整除。

您之前可以通过简单的数学运算来相对轻松地解决这个问题。我写了几行代码,它们允许你提供一个点直径值,以及一个预期的点间距 - 它将尝试近似最接近的点间距,这将导致整数个点。

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

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

CAShapeLayer

您现在可以获得以下输出:

enter image description here

如果你想在// 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]; 中使用它,我建议将其子类化并添加UIView作为子图层。您还需要添加一个遮罩层,以便将视图的内容屏蔽到边框内。

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

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

答案 1 :(得分:3)

执行您尝试的操作的最佳方法是绘制圆UIBezierPath,并将路径设置为虚线样式。虚线样式路径代码取自this answer

UIBezierPath * path = [[UIBezierPath alloc] init];
[path addArcWithCenter:center radius:50 startAngle:0 endAngle:2 * M_PI clockwise:YES];
[path setLineWidth:8.0];
CGFloat dashes[] = { path.lineWidth, path.lineWidth * 2 };
[path setLineDash:dashes count:2 phase:0];
[path setLineCapStyle:kCGLineCapRound];

// After you have the path itself, you can either make 
// an image and set it in a view or use the path directly
// in the layer of the view you want to.
// This is the code for the image option.

UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 20), false, 2);
[path stroke];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();