0
votes

I would like to load instances of a class that contains a uibezierPath, and redraw these previous paths at the launch of the app. The dictionary returns the correct instances, but I cannot draw the paths : the view is created in the storyboard, so I used initWithCoder, if I use viewDidLoad, this method is not called. And the error is :

previousArrays : ( { firstPath = ""; }, { firstPath = ""; }, { firstPath = ""; }, { firstPath = ""; } ) Dec 30 17:02:36 iPhone MyProject[1818] : CGContextAddPath: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Here is my code : (after a touch, a path is saved, then when starting the app again, the error appears. When I draw though, there is no problem. Drawing the path works. It is when returning to the app, and drawing in initWithCoder, that the problem appears.)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:myPath];//nscoding compliant
    DataForPath *firstPath = [[DataForPath alloc] init];
    firstPath.path = bezierPath;
    firstPath.colorInArray = @(currentColor);
    NSDictionary *dict = @{@"firstPath":firstPath};

    [SaveData saveData:dict];
}


-(id)initWithCoder:(NSCoder *)aDecoder{
    if ( !(self=[super initWithCoder:aDecoder])) return nil;
    //...
    myPath = CGPathCreateMutable();
    CGContextRef context = UIGraphicsGetCurrentContext();
    NSArray *previousArrays = [SaveData loadData];
    //NSLog("previousArrays : %@", previousArrays )...
    for ( NSDictionary*dict in previousArrays){
        UIBezierPath *eachPath = dict[@"path"];
        int color = [dict[@"colorInArray"] intValue];
        UIColor *objectColor = [self.possibleColor objectAtIndex:color];

        CGContextAddPath(context, eachPath.CGPath);
        CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
        CGContextDrawPath(context, kCGPathStroke);

        /*
        CGContextSetStrokeColorWithColor(context, objectColor.CGColor);
        CGContextSaveGState(context);
        [eachPath stroke];
        CGContextRestoreGState(context);
        */
    }
    return self;
}

EDIT : the previous paths in the for loop are not drawn?

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    if ( firstLaunchWithPreviousPaths ){
        for ( NSDictionary*dict in previousArrays){
            NSLog(@"firstLaunch"); //is called
            UIBezierPath *eachPath = dict[@"path"];

            CGContextAddPath(context, eachPath.CGPath);
            CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
            CGContextDrawPath(context, kCGPathStroke);
            //nothing is drawn?
        }
    }
    //with touchesEnd : this works
    /*
    CGContextAddPath(context, myPath);
    CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
    CGContextDrawPath(context, kCGPathStroke);
     */
}
1

1 Answers

2
votes

The error message tells you the problem. You are saying:

CGContextRef context = UIGraphicsGetCurrentContext();

But there is no current context in initWithCoder:.

You can only draw in a place where there is a graphics context. Either make one, or move your code to a place where there is one (such as drawRect:).

Or, if you are trying to construct a mutable CGPath, make no reference to any graphics context: work with the path, not a context. CGMutablePath has a whole set of functions of its own for constructing the path. But of course then you cannot stroke or draw it - it's just a path. You will be able to stroke or draw it later, when you have a graphics context; you give the context the path and now you can stroke or draw it. Stroking and drawing are something that can only happen in a graphics context. And you don't have one here.