ビューで塗りつぶしパターンをテクスチャとして使用しようとしています。CGPatternCreate への呼び出しを設定しましたが、変換として何を渡すか正確にはわかりません。現在の行列を渡そうとしましたが、回転すると奇妙な結果が生じます。
形状は時計回りに回転し、パターンは反時計回りに回転するビューの例を作成しました。回転の方向を変更するために、さまざまな方法で y 軸をスケーリングしてみました。
//
// 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, &drawPattern, &releasePattern };
CGPatternRef pat = CGPatternCreate(img, rect, t, w, h, kCGPatternTilingConstantSpacing, true, &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