iOS CGContextDrawLinearGradient intermittently draws all black in app instead of gradient

Viewed 25

I have a UIView subclass which draws a grid of gradient colors. I use instances of this custom view at 3 different screens in my app. Most of the time it works fine. However, randomly, upon app relaunch, the gradients all show black with a very thin edge which has color. What's even odder is that when the gradients on one the screen breaks, then, then gradients on the other 2 screens also break at the same time. The only way to fix it is to quit the app completely and relaunch it and it automatically starts working again.

I have been having a very hard time trying to narrow down this issue as it's so intermittent.

Code is attached below.

I would recommend opening these images in a new tab and zooming on the edges of the gradients. You will notice the color is there at the very edge.

Here's how it looks when working:

enter image description here

enter image description here

Here's how it looks when it breaks:

enter image description here

enter image description here

Code:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    //NSLog(@"DRAW: %@",NSStringFromCGRect(self.bounds));
    
    if (arrayOfTagRects.count>0) {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGFloat locations[2]= { 0.0, 1.0 };
        
        
        
        
        
        for (NSInteger i=0;i<arrayOfTagRects.count;i++) {
            
            
            NSDictionary *toDraw = arrayOfTagRects[i];
            
            CGContextSaveGState(ctx);
            CGContextSetFillColor(ctx, CGColorGetComponents([[UIColor clearColor] CGColor]));
            
            
            UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:[(NSValue*)[toDraw objectForKey:@"bezierrect"] CGRectValue] byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(8, 8)];
          
            [bezierPath addClip];
            CGContextAddPath(ctx, bezierPath.CGPath);
            
            CGGradientRef selectedgradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)[NSArray arrayWithObjects:
                                                                                                 (id)((UIColor*)[toDraw objectForKey:@"startColor"]).CGColor,
                                                                                                 (id)((UIColor*)[toDraw objectForKey:@"endColor"]).CGColor, nil], locations);
            
            CGContextDrawLinearGradient(ctx, selectedgradient,[(NSValue*)[toDraw objectForKey:@"gradientstartpoint"] CGPointValue],[(NSValue*)[toDraw objectForKey:@"gradientendpoint"] CGPointValue] , 0);
            
            [bezierPath fill];
            
            
            
            if ((!self.myClass && i==MS.selectedColor) || (self.myClass && i==self.myClass.classColor)) {
                [[UIImage imageNamed:@"done"] drawInRect:AVMakeRectWithAspectRatioInsideRect(CGSizeMake(1, 1), CGRectInset([(NSValue*)[toDraw objectForKey:@"bezierrect"] CGRectValue], 8, 8))];
            }
            
            CGContextRestoreGState(ctx);
            CGGradientRelease(selectedgradient);
            
        }
        
        CGColorSpaceRelease(colorSpace);
        
        
    } else {
        heightOfView = 0;
    }
    
}
0 Answers
Related