title: CGPatternCreate transform
body: <p>I am trying to use a fill pattern as a texture in my view. I set up the call to CGPatternCreate but I do not know exactly what to pass as the transform. I tried passing the current matrix but that produces strange results under rotation.</p>
  
  <p>I've made an example view where the shape rotates clockwise but the pattern rotates counterclockwise. I even tried scaling the y-axis in various ways to change the direction of the rotation.</p>
  
  <pre><code>//
  //  TestView.m
  //  test
  //
  //  Created by Blake Hegerle on 8/15/12.
  //  Copyright (c) 2012 Blake Hegerle. All rights reserved.
  //
  
  #import "TestView.h"
  
  const float RATE = (float)1/60;
  
  void drawPattern(void *info, CGContextRef ctx) {
      CGImageRef img = (CGImageRef)info;
  
      CGRect bounds = CGRectMake(0, 0, CGImageGetWidth(img), CGImageGetHeight(img));
      CGContextDrawImage(ctx, bounds, img);
  }
  
  void releasePattern(void *info) {
      CGImageRef img = (CGImageRef)info;
      CFRelease(img);
  }
  
  @implementation TestView
  
  -(void)awakeFromNib
  {
      clock = 0;
  
      [NSTimer scheduledTimerWithTimeInterval:RATE
                                       target:self
                                     selector:@selector(tick:)
                                     userInfo:nil
                                      repeats:YES];
  }
  
  - (void)drawRect:(CGRect)rect
  {
      CGContextRef ctx = UIGraphicsGetCurrentContext();
  
      // set transform
      CGContextTranslateCTM(ctx, rect.size.width/2, rect.size.height/2);
      CGContextRotateCTM(ctx, clock*RATE/5);
  
      // get the image
      CGImageRef img = [UIImage imageNamed:@"zebra.jpeg"].CGImage;
      double w = CGImageGetWidth(img), h = CGImageGetHeight(img);
      CFRetain(img);
  
      // set the pattern transform
      CGAffineTransform t0 = CGContextGetCTM(ctx);
      CGAffineTransform t1 = CGAffineTransformMakeScale(1, -1);
      CGAffineTransform t2 = CGAffineTransformMakeTranslation(0, rect.size.height);
      CGAffineTransform t = CGAffineTransformConcat(t2, CGAffineTransformConcat(t1, t0));
  
      // create the pattern
      CGPatternCallbacks cb = { 0, &amp;drawPattern, &amp;releasePattern };
      CGPatternRef pat = CGPatternCreate(img, rect, t, w, h, kCGPatternTilingConstantSpacing, true, &amp;cb);
  
      // change to pattern colorspace
      CGColorSpaceRef pcs = CGColorSpaceCreatePattern(nil);
      CGContextSetFillColorSpace(ctx, pcs);
      CGColorSpaceRelease(pcs);
  
      // apply the pattern
      float alpha[] = { 1 };
      CGContextSetFillPattern(ctx, pat, alpha);
      CFRelease(pat);
  
      // fill a rect
      double sz = rect.size.width / 5;
      CGContextFillRect(ctx, CGRectMake(0, 0, sz, sz));
  }
  
  -(void)tick:(NSTimer *)t
  {
      clock++;
      [self setNeedsDisplay];
  }
  
  @end
  </code></pre>