Question

I am creating progress view by using CALayer by following

Header class

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface ProgressBar : UIView
@property (strong, nonatomic) CALayer *subLayer;

@property (nonatomic) CGFloat progress;
@end

Implementation class

@implementation ProgressBar

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

        self.subLayer = [CALayer layer];
        self.subLayer.frame = self.bounds;

        self.subLayer.backgroundColor = [UIColor orangeColor].CGColor;
        [self.layer addSublayer:self.subLayer];
    }
    return self;
}
- (void)setProgress:(CGFloat)value {
    NSLog(@"what is going on here");
    if (self.progress != value) {
        self.progress = value;
        [self setNeedsLayout];
    }
}

- (void)layoutSubviews {
    CGRect rect = [self.subLayer frame];
    rect.size.width = CGRectGetWidth([self bounds]) * self.progress;
    [self.subLayer setFrame:rect];
}

In my viewcontroller, I am doing

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.pBar = [[ProgressBar alloc] initWithFrame:CGRectMake(0, 50, 320, 10)];

    [self.view addSubview:self.pBar];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)click:(id)sender {
    [self.pBar setProgress:.8];

}

When (IBAction)click is fired, I am getting into the infinitive loop like the picture below enter image description here

Does anyone know what I am getting into this loop. Please advice me on this issue. Thanks

Was it helpful?

Solution

The problem is that your setProgress: method calls the setProgress: method - recursion.

- (void)setProgress:(CGFloat)value {
    NSLog(@"what is going on here");
    if (self.progress != value) {
        self.progress = value; // <-- This calls [self setProgress:value]
        [self setNeedsLayout];
    }
}

Change the bad line to:

_progress = value;

Setting the ivar directly is always required when you implement the setter method of a property.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top