1

I am trying to create a circular progress bar around an image as shown in the screenshot below. So far I have managed to create a round image with a green border using the code below:

    self.image.layer.cornerRadius = self.image.frame.size.width / 2
    self.image.clipsToBounds = true
    self.image.layer.borderWidth = 6.0
    self.image.layer.borderColor = UIColor.greenColor.CGColor

My question is, how do I create a circular progress bar from the border than I have set? Or do I need to remove this border and take a different approach?

Like This

Swinny89
  • 7,273
  • 3
  • 32
  • 52
Rahul singh
  • 251
  • 3
  • 20

2 Answers2

5

I understood your problem and I suggest you to use some library to create such a loader you can find many of the swift libraries. On of them is FPActivityIndicator, it is the same circular loader which you are searching for, you only have to adjust the radius and position of the loader to move it around the image Here is an attached screenshot of the working project

if you need further help you can send me message and if it helps please accept the answer. Thanks

  • Original post is asking for circular progress bar around image!! – Ketan Parmar Jul 28 '16 at 04:39
  • @Lion challenge was to create circular bar, and one can easily adjust it around an image, :) – Muhammad Jahanzaib Jul 29 '16 at 05:47
  • No that is not that much easy as you think. you have to manage it for every device. Just try it with this library which you have mentioned in answer and check in every device and check it with different size of imageview which take place between circular progress. (i.e try onece (50,50) then try (300,300) ) etc! – Ketan Parmar Jul 29 '16 at 05:54
2

I have customized the answer of WDUK in stack overflow post according to your need,

It is something like,

TestView.h

 #import <UIKit/UIKit.h>

 @interface TestView : UIView

 @property (nonatomic) double percent;

 @end

TestView.m

 #import "TestView.h"


@interface TestView () {
CGFloat startAngle;
CGFloat endAngle;
}

@end

@implementation TestView



- (id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];
   if (self) {
    // Initialization code
    self.backgroundColor = [UIColor whiteColor];

    // Determine our start and stop angles for the arc (in radians)
    startAngle = M_PI * 1.5;
    endAngle = startAngle + (M_PI * 2);

  }
 return self;
}

- (void)drawRect:(CGRect)rect
{  

 CGFloat constant = rect.size.width/ 5;

UIImage *img = [UIImage imageNamed:@"lion.jpg"]; // lion.jpg is image name
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(rect.origin.x + constant/2, rect.origin.y + constant/2, rect.size.width-constant, rect.size.height - constant)];
imgView.image = img;
imgView.layer.masksToBounds = YES;
imgView.layer.cornerRadius = imgView.frame.size.width / 2;

UIBezierPath* bezierPath = [UIBezierPath bezierPath];

// Create our arc, with the correct angles
[bezierPath addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2)
                      radius:constant*2
                  startAngle:startAngle
                    endAngle:(endAngle - startAngle) * (_percent / 100.0) + startAngle
                   clockwise:YES];

// Set the display for the path, and stroke it
bezierPath.lineWidth = 20;
[[UIColor redColor] setStroke];
[bezierPath stroke];



[self addSubview:imgView];

}

@end

ViewController.m

 #import "ViewController.h"
#import "TestView.h"

@interface ViewController (){
TestView* m_testView;
NSTimer* m_timer;
}

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Init our view

CGRect frame = CGRectMake(50, 50, 200, 200);

m_testView = [[TestView alloc] initWithFrame:frame];
m_testView.percent = 0;
[self.view addSubview:m_testView];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidAppear:(BOOL)animated
{
// Kick off a timer to count it down
m_timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(increamentSpin) userInfo:nil repeats:YES];
}

- (void)increamentSpin
{
  //  increament our percentage, do so, and redraw the view
 if (m_testView.percent < 100) {
    m_testView.percent = m_testView.percent + 1;
    [m_testView setNeedsDisplay];
}
else {
    [m_timer invalidate];
    m_timer = nil;
  }
}

- (void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
}

@end

If you are decreasing frame size from viewcontroller then you should reduce bezierPath.lineWidth accordingly to show respectively thin progress around imageview.

And this is working perfact, i have tested it!!!

Community
  • 1
  • 1
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75