0

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);

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Ok sure. But CGContextFillRects asks specifically for CGRect*. What should I do? – Master Crouch Jun 08 '16 at 20:17
  • 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. Have you checked to make sure that you actually have a non-zero frame at the time you're constructing it (i.e. in `-setupView`)? In other words, are you sure that `minorPlotLines` is actually **empty** or is it filled with an array of `CGRectZero`s? – fullofsquirrels Jun 08 '16 at 21:22
  • You are right. I wish you posted an answer so I could give you internet points. Thanks a bunch. One question: If I intend to plot a graph grid with CGContextFillRects, is CGContextFillRects more efficient than CGContextAddLineToPoint? Are rectangles better than lines? My gird lines will be 2 pixels thick or so and will update their location at 60 fps. – Master Crouch Jun 08 '16 at 21:55
  • I see you posted as a separate question; I'll post my answer to **this** question as an actual answer, then take a look more closely at your other question. – fullofsquirrels Jun 08 '16 at 22:15

1 Answers1

1

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).

fullofsquirrels
  • 1,828
  • 11
  • 16