title: Nesting GetContext() calls - Is this Custom UILabel reusing the CoreGraphics context?
body: <p>My issue is as follows - I'm able to use the below function: takeSnapshotOfScreen to take a properly scaled snapshot of the screen when there exists only an image in any UIView. However, when I add a label, as seen below, the final snapshot image saves down with a smaller, squished version of the larger image, superimposed in the center where the CustomLabelClass should be, instead of the label containing actual text. </p>
  
  <p>My guess is that the call to get the CG context, from within the function: drawTextInRect (in CustomLabelClass), seems to be reusing the context retrieved by the calling function takeSnapshotOfScreen, since it is never popped, I'm guessing.</p>
  
  <p>If my guess is correct, how does one properly handle such a scenario?</p>
  
  <p>My sincere thanks in advance to any assistance. I really appreciate it!</p>
  
  <ul>
  <li>Code &amp; Details-</li>
  </ul>
  
  <p>Below is a sample image, demonstrating this superimposed/context problem.</p>
  
  <p><img src="https://i.stack.imgur.com/iPEo9.jpg" alt="enter image description here"></p>
  
  <p>I have a custom UILabel class where I'm overriding drawTextInRect to draw a border around the text:</p>
  
  <pre><code>@interface CustomLabelClass : UILabel {
      @property (nonatomic, strong) UIColor *innerColor;
      @property (nonatomic, strong) UIColor *borderColor;
  }
  
  @implementation CustomLabelClass
  @synthesize innerColor, borderColor;
  ...
  - (void)drawTextInRect:(CGRect)rect {
  
      CGContextRef context = UIGraphicsGetCurrentContext();
      CGContextSaveGState(context);
      CGContextSetTextDrawingMode(context, kCGTextFill);    
  
      if(innerColor)
          [self setTextColor:innerColor];
  
      // Draw the text without an outline
      [super drawTextInRect:rect];
  
      CGImageRef alphaMask = NULL;
  
      // Create a mask from the text
      alphaMask = CGBitmapContextCreateImage(context);
  
      // Outline width
      CGContextSetLineWidth(context, 4);
      CGContextSetLineJoin(context, kCGLineJoinRound);
  
      // Set the drawing method to stroke
      CGContextSetTextDrawingMode(context, kCGTextStroke);
  
      // Outline color
      if(borderColor)
          self.textColor = borderColor;
  
      // notice the +1 for the y-coordinate. this is to account for the face that the outline appears to be thicker on top
      [super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y+1, rect.size.width, rect.size.height)];
  
      // Draw the saved image over the outline. Invert because CoreGraphics works with an inverted coordinate system
      CGContextTranslateCTM(context, 0, rect.size.height);
      CGContextScaleCTM(context, 1.0, -1.0);
      CGContextDrawImage(context, rect, alphaMask);
  
      // Clean up because ARC doesnt handle CoreGraphics
      CGImageRelease(alphaMask);
  
      UIGraphicsEndImageContext();
  }
  </code></pre>
  
  <p>I have another class that uses the CustomLabelClass, below:</p>
  
  <pre><code>#import "CustomLabelClass.h"
  
  @implementation CustomViewController
  
  -(void)createCustomLabel{
  
  //...create a CustomLabelClass *newLabel object...etc.
      ...
  
  // add it to the view
      [[[self view] viewWithTag:ViewContainingImageAndCustomLabels] addSubview:newLabel];
  }
  
  
  -(void)updateCurrentImage{
  
      // Assume that the object: mainImage, is a global UIImage, for purposes of these code snippets.
  
      UIImageView *mainImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, mainImage.size.width, mainImage.size.height)];        
      mainImageView.image = mainImage;
      [mainImageView setTag:ViewTypeMainPhoto];
  
      // we always want the image to be the underlying view, so insert it at Index:0
      [[[self view] viewWithTag:ViewContainingImageAndCustomLabels] insertSubview:mainImageView atIndex:0];
  }
  
  
  -(UIImage *)takeSnapshotOfScreen{
  
      // Mostly taken from: http://developer.apple.com/library/ios/#qa/qa1703/_index.html
      //
      // Create a graphics context with the target size
      // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
      // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
  
      CGSize imageSize = [[UIScreen mainScreen] bounds].size;
  
      if (NULL != UIGraphicsBeginImageContextWithOptions){
          UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0.0f); // 0.0f scale is for retina bc *WithOptions captures native resolution
      }else{
          UIGraphicsBeginImageContext(imageSize);
      }
  
      CGContextRef context = UIGraphicsGetCurrentContext();
  
      // Iterate over every window from back to front
      for (UIView *tempView in [[[self view] viewWithTag:ViewContainingImageAndCustomLabels] subviews])
      {
              // -renderInContext: renders in the coordinate space of the layer,
              // so we must first apply the layer's geometry to the graphics context
              CGContextSaveGState(context);
  
              // Center the context around the window's anchor point
              CGContextTranslateCTM(context, [tempView center].x, [tempView center].y);
              // Apply the window's transform about the anchor point
              CGContextConcatCTM(context, [tempView transform]);
              // Offset by the portion of the bounds left of and above the anchor point
              CGContextTranslateCTM(context,
              -[tempView bounds].size.width * [[tempView layer] anchorPoint].x,
              -[tempView bounds].size.height * [[tempView layer] anchorPoint].y);
  
              // Render the layer hierarchy to the current context
              [[tempView layer] renderInContext:context];
  
              // Restore the context
              CGContextRestoreGState(context);
      }
  
      // Retrieve the screenshot image
      UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  
      UIGraphicsEndImageContext(); // remove context from stack
  
      return image;
  }
  </code></pre>
  
  <p>and finally a function that just calls the above (simplified below):</p>
  
  <pre><code>-(void)doEverything{
      [self createCustomLabel];
      [self updateCurrentImage];
      [self takeSnapshotOfScreen];
  }
  
  @end
  </code></pre>