iPhone_TouchEvent のバックアップ(No.3) - アールメカブ

アールメカブ


iPhone_TouchEvent のバックアップ(No.3)


Programming

_ 簡単なプログラム

背景に画像を設定し、その全面にクラゲを泳がせる

View-Basedクラスを作成し ViewController?クラスに以下の変数を追加

	UIImageView *contentView;
	UIImageView *fishes;
	BOOL inSide;
	CGPoint start;

またタッチメソッドを追加

-(void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*) event;
-(void) touchesMoved:(NSSet*) touches withEvent:(UIEvent*) event;
-(void) touchesEnded:(NSSet*) touches withEvent:(UIEvent*) event;

次に ControllerView?.mを編集 loadView関数を追加

- (void)loadView
{

  //メインの画面矩形サイズを取得

	CGRect appRect = [[UIScreen mainScreen] applicationFrame];
 // その矩形サイズのビューを作成し
	contentView = [[ UIView alloc] initWithFrame:appRect];
	contentView.backgroundColor = [UIColor whiteColor];
	
 // ControllerViewクラスのビューに代入
	self.view = contentView;
	[contentView release];	
// 座標系を作成したビューにあわせる
	appRect.origin = CGPointMake(0.0f,0.0f);
	
 // 背景画像の準備
	UIImage* backgroundImage = [UIImage
                           imageNamed:@"kaitei2.png"];
 // 背景にセット。なおこのファイル冒頭で
   //#import <QuartzCore/QuartzCore.h> をincludeしておく	
	[contentView layer].contents = (id)backgroundImage.CGImage;
	[backgroundImage release];
	
 //	重ね合わせる画像の準備 .60ピクセル矩形の画像を画面
	fishes = [[UIImageView alloc] 
         initWithFrame:CGRectMake(0.0f, 0.0f, 60.0f, 60.0f)];
	//[fishes setUserInteractionEnabled:YES];
	NSMutableArray *bflies = [[NSMutableArray alloc] init];
	for (int i = 1; i <= 9; i++) {
		NSString *cname = [NSString
                    stringWithFormat:@"kurage%d.png", i];
		UIImage *img = [UIImage imageNamed:cname];
		if (img) [bflies addObject:img];
		[cname release];
	}
	
  // 画像をアニメーションさせる 
	[fishes setAnimationImages:bflies];
	fishes.animationDuration = 2.0f;//0.75f
	[fishes startAnimating];	
	[contentView addSubview:fishes];
	[fishes release];
}

これで描画される。次に画像をドラッグして移動させる処理

-(void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*) event
{
 // タップ開始位置の取得
	CGPoint pt2 = [[touches anyObject] 
            locationInView:contentView];
 // その座標が、魚画像の矩形内か調べる
	BOOL Y = CGRectContainsPoint(fishes.frame, pt2);
	
	if(Y == YES){
		inSide = YES;//フラグをセット
		start = pt;
	}else{
		inSide = NO;
	}
	
}
-(void) touchesMoved:(NSSet*) touches withEvent:(UIEvent*) event
{
	if(inSide){//フラグがセットされているなら移動させる
		UITouch * touch = [touches anyObject];
		CGPoint pt  = [touch locationInView:contentView];
		// そして魚を移動する
		CGRect frame = [fishes frame];
		frame.origin.x = pt.x - start.x;
		frame.origin.y = pt.y - start.y;		
		
		[fishes setFrame:frame];
	}
 }
-(void) touchesEnded: (NSSet*)touches withEvent:(UIEvent*)event
{
	inSide = NO;//Flag をアンセット
}

_ 参考ページ

ここがとても参考になる.

  - (CGPoint)locationInView:(UIView *)view

locationInView?:hogeは 指定したビュー hoge の座標系でレシーバ(タッチ)の現在の座標を返す。nilを指定した場合ウインドウの座標系になる。(参照

これは hoge の現在の位置を,親ビューの座標系で返せ,ということか. 以下のループ構造でよく使われる.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	for (UITouch *touch in touches) {
		clickPos = [touch locationInView:self];
		break;
	}	
}

ビューの座標系についてはここが詳しい

また以下はここからの引用.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   // We only support single touches, so get the touch from allTouches
   UITouch *touch = [[event allTouches] anyObject];

   // Only move the placard view if the touch was in the placard view
   if ([touch view] != placardView)
   {
       // In case of a double tap outside the placard view, update the placard's display string
       if ([touch tapCount] == 2)
       {
           [placardView setupNextDisplayString];
       }
       return;
   }
   // Animate the first touch
   CGPoint touchPoint = [self convertPoint:[touch locationInView:self] fromView:placardView];
   [self animateFirstTouchAtPoint:touchPoint];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [[event allTouches] anyObject];

   // If the touch was in the placardView, move the placardView to its location
   if ([touch view] == placardView)
   {
       CGPoint location = [touch locationInView:self];
       location = [self convertPoint:location fromView:placardView];
       placardView.center = location;
       return;
   }
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [[event allTouches] anyObject];

   // If the touch was in the placardView, bounce it back to the center
   if ([touch view] == placardView)
   {
       // Disable user interaction so subsequent touches don't interfere with animation
       self.userInteractionEnabled = NO;
       [self animatePlacardViewToCenter];
       return;
   }
}