Search code examples
ioscocoa-touchrenderingmaskuibezierpath

Cocoa Touch: Mask ignored when image is rendered: renderInContext:UIGraphicsGetCurrentContext()


I am trying to render a masked view using renderInContext:UIGraphicsGetCurrentContext(). I am masking a white colored view which is the subView of a gray colored view. This works just fine for display: I end up with a white shape against a gray background, but when I render the mask is ignored, and all I see is white in the resulting image.

Mask in a UIView subclass

- (void)drawRect:(CGRect)rect
{
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        CGMutablePathRef patheToMask = CGPathCreateMutable();
        CGRect scrollMaskRect = CGRectMake(30, 30, 100, 100);
        UIBezierPath *scrollMask = [UIBezierPath bezierPathWithRoundedRect:scrollMaskRect cornerRadius:30];
        CGPathAddPath(patheToMask, nil, scrollMask.CGPath);
        [maskLayer setPath:patheToMask];
        CGPathRelease(patheToMask);
        self.layer.mask = maskLayer;
}

render code

-(void)renderImage {
    CGSize renderSize = CGSizeMake(masterView.frame.size.width, masterView.frame.size.height);
    UIGraphicsBeginImageContext(renderSize);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextConcatCTM(context, [[masterView layer] affineTransform]);
    [[masterView layer] renderInContext:UIGraphicsGetCurrentContext()];
    renderedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGContextRestoreGState(context);
    UIImageWriteToSavedPhotosAlbum(renderedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    masterView.transform = CGAffineTransformIdentity;
}

Here is the project http://owolf.net/uploads/StackOverflow/MaskWeirdness.zip


Solution

  • According to the documentation, renderInContext:UIGraphicsGetCurrentContext() does not support masking.

    https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CALayer_class/Introduction/Introduction.html

    From the docs:

    Important: The OS X v10.5 implementation of this method does not support the entire Core Animation composition model. QCCompositionLayer, CAOpenGLLayer, and QTMovieLayer layers are not rendered. Additionally, layers that use 3D transforms are not rendered, nor are layers that specify backgroundFilters, filters, compositingFilter, or a mask values. Future versions of OS X may add support for rendering these layers and properties.