CALayerにアニメーションを追加して、NSOperationからレイヤの位置を確認する方法
コード
TestViewをwindowに追加して、コンパイルし、画面をクリックするだけ。
TestViewヘッダファイル
@interface TestView : UIView { NSOperationQueue *operationQueue_; } @property (nonatomic, retain) NSOperationQueue *operationQueue; @end
TestViewの定義
// // TestView.m // AnimTest // // Created by nobuyuki on 10/08/17. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import "TestView.h" #import <QuartzCore/QuartzCore.h> @implementation TestView @synthesize operationQueue = operationQueue_; #pragma mark - #pragma mark test int cnt; - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { cnt = 10; CGFloat layerWidth = self.bounds.size.width / cnt; CGFloat layerHeight = 10; int i = 0; for (i = 0; i < cnt; i++) { CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, layerWidth / 2, layerHeight); layer.position = CGPointMake(layerWidth * i + layerWidth / 2, layerHeight / 2); layer.backgroundColor = [UIColor colorWithHue:1.0f / cnt * i saturation:1.0f brightness:1.0f alpha:1.0f].CGColor; [self.layer addSublayer:layer]; } self.operationQueue = [[[NSOperationQueue alloc] init] autorelease]; /* CheckOperation *op = [[CheckOperation alloc] init]; op.layer = [self.layer.sublayers objectAtIndex:0]; [self.operationQueue addOperation:op]; */ CALayer* checkLayer = [self.layer.sublayers objectAtIndex:0]; [self.operationQueue addOperationWithBlock:^{ for ( ; ; ) { id pool = [[NSAutoreleasePool alloc] init]; // (追記) [NSThread sleepForTimeInterval:0.01f]; [CATransaction begin]; [CATransaction setDisableActions:YES]; NSLog(@"test %x %@", checkLayer, [NSValue valueWithCGPoint: ((CALayer *)checkLayer.presentationLayer).position]); [CATransaction commit]; [pool release]; } }]; } return self; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { for (CALayer *layer in self.layer.sublayers) { CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"]; anim.duration = 1.0f; anim.fromValue = [NSValue valueWithCGPoint:layer.position]; anim.toValue = [NSValue valueWithCGPoint:CGPointMake(layer.position.x, self.bounds.size.height)]; anim.autoreverses = YES; anim.repeatCount = UINT_MAX; [layer addAnimation:anim forKey:@"move"]; } } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ - (void)dealloc { self.operationQueue = nil; [super dealloc]; } @end
なぜかわからないが、別スレッドからでもCATransactionとpresentationLayerを使えば値の取得ができることがわかった。