Master Crouch Master Crouch - 6 months ago 28
Objective-C Question

CGContextFillRects: CGRect* not working. Assigned CGRect items do not get saved

I am trying to save an array of CGRect to use with CGContextFillRects but the CGRect variables I assign to my minorPlotLines array don't seem to get saved. By the time the object here draws itself minorPlotLines is empty! Does anyone know what is going on?

@interface GraphLineView () {
int numberOfLines;
CGRect *minorPlotLines;
}


@end


@implementation GraphLineView


- (instancetype) initWithFrame: (CGRect) frame {
self = [super initWithFrame:frame];
if (self) {
// Init code
[self setupView];
}
return self;
}

- (instancetype) initWithCoder: (NSCoder *) aDecoder {
if(self == [super initWithCoder:aDecoder]){
[self setupView];
}
return self;
}

- (void) dealloc {
free(minorPlotLines);
}

- (void) setupView {

numberOfLines = 40;
minorPlotLines = malloc(sizeof(struct CGRect)*40);

for(int x = 0; x < numberOfLines; x += 2){
//minorPlotLines[x] = *(CGRect*)malloc(sizeof(CGRect));
minorPlotLines[x] = CGRectMake(x*(self.frame.size.width/numberOfLines), 0, 2, self.frame.size.height);

// minorPlotLines[x+1] = *(CGRect*)malloc(sizeof(CGRect));
minorPlotLines[x+1] = CGRectMake(0, x*(self.frame.size.height/numberOfLines), self.frame.size.width, 2);

}

[self setNeedsDisplay];
}

- (void) drawRect:(CGRect)rect {
// Drawing code
[super drawRect:rect];

for(int x = 0; x < numberOfLines; x += 2){
NSLog(@"R %d = %f", x, minorPlotLines[x].origin.x);
NSLog(@"R %d = %f", x+1, minorPlotLines[x+1].origin.y);
}

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor yellowColor] CGColor]);
CGContextFillRects(context, minorPlotLines, numberOfLines);

}

Answer

I tried pulling your code (to construct the contents of minorPlotLines and later read the contents back out) into another project, and it does seem to preserve the contents just fine, so your basic code itself seems sound.

I would check to make sure that you actually have a non-zero frame at the time you're constructing the array minorPlotLines (i.e. in -setupView). It's quite common for early-stage UI class loading callbacks to be called at a time when your class is only partially constructed (e.g. UIViewController class' callback -viewDidLoad), leaving you no choice but to defer certain decisions until later in the loading process. Layout in particular happens relatively late in the game, and since your -setupView method is called right within an -init method I'm guessing the framework hasn't provided any layout to your class yet, and hence it has no usable frame (i.e. your frame is effectively equivalent to CGRectZero).