iOS:タッチしている間だけ移動する

何か動かしてみたい

interFaceBuilderを利用すると、色々簡単にできそうなことが分かりましたが
やっぱりゲームっぽいアプリも作成してみたいです。ということで、とりあえず
タッチしている間だけ移動するようなサンプルを作成しました。
 
手始めにjQueryで作成しました。濃いグレーの部分をプレスしている間だけ
上部の■が右に移動します。jQueryの説明はソースに書いたので確認して下さい。
これをObjective-Cに書き換えてみます。
→参考:jQueryでの移動サンプル
 
 

youtube

実際に作成したサンプルをyoutubeにアップしました。次項でソースについて説明します。
独学xcode: タッチしている間だけ移動する

 
 
 

ソースの説明

ヘッダファイルの記述

interfaceBuilderに登録したのは以下、2つラベルだけです。
jQueryのサンプルではdivを利用しましたが、objective-cでは何を利用して良いか
分からなかったので「とりあえず」ラベルにしました。
——————————————————
IBOutlet UILabel *moveArea;
IBOutlet UILabel *debugArea;
——————————————————
ラベルを使うことを決めた後で知ったのですが、ラベルにはボタンのようなイベントを
設定できません!。しかしネットで調べたら、不可能ではないのでラベルで続行する
ことにしました。というわけでヘッダファイルにはイベントの登録をしていないのです。
→参考:UILabelやUIImageViewのタッチイベントを取得する
 
 

実装ファイルの記述

ほとんど上記リンクを参考にしているため、細かい部分の文法が分かりません..。
しかし勢いが大切。とりあえず分かった部分だけメモ。
※全てのソースをここに書くと長くなるので、ソースはyoutubeで確認して下さい。
 画質を720pにしてフルスクリーンで見れば文字も読めると思います。

新規プロジェクトで選択した「view-based Application」の実装ファイルには
あらかじめ、色々なメソッド?が記述されているが、コメントアウトされている。
以下のviewDidLoadも、その1つで、このコメントを外して処理を追加。
 
メソッド名から察するに、画面の準備が完了されたら実行されるメソッドで
jQueryでいうreadyイベントみたいなものだと思う。
——————————————————
– (void)viewDidLoad {
 [super viewDidLoad];
 moveArea.userInteractionEnabled = YES;
 moveArea.tag = 100;
}
——————————————————
moveAreaはラベルなので、デフォルトではタップを受け付けないらしい。なので
userInteractionEnabledプロパティをYESにしてタップを受け付けるようにする。
このときにtagを数値で設定しなくてはいけないそうです(サンプルでは100)。
 
また、jQueryではsetInterval用に変数moveTimerを作成しましたが
objecteb-cでは以下の様にtimerクラスを作成するそうです。
——————————————————
NSTimer *moveTimer;
——————————————————
 
そしてメソッド(javaScriptのfunction?)の作成部分の構文がよく分かりません。
参考サイトとしては以下のサイトをメモ。
→参考:逆引きObjective-C「メソッドの定義
 
上記サイトからサンプルを解読すると、例えば以下の部分は、インスタンスメソッドで
返値は無く、引数は(NSTimer *)timerということになる。
——————————————————
-(void) moveFunc:(NSTimer *)timer
——————————————————
※(NSTimer *)timerというのは型指定の部分が(NSTimer *)で、変数名が
 timerということなのかな?

でも、今回moveFuncで引数なんて利用してないから、引数の表記を消したらエラーになった。
timerで実行するメソッドには必須なのでしょう。
 
 
touchesBeganやtouchesEndedの構文はさらに複雑。 
——————————————————
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
——————————————————
でもtouchesが引き数名なのは理解しました。withEvent以降はよく分かりませんが、
多分定型なのかな?
→参考:引数touchesを利用した例があるサイト。
 
で、引数のtouchesからタッチの情報を以下の1行目で取得し、それを2行目のif文で
判断しているのだと思う。
——————————————————
UITouch *touch = [touches anyObject];
if ( touch.view.tag == moveArea.tag ){
——————————————————
条件式のtouch.view.tagは、タッチ情報からタグを取得して、それをmoveAreaのtag
と比較しているのだね。だからこのテクニックは、ラベルにイベントを設定しているのではなく
画面全体のタップを検知して、タップされた場所がラベルかどうかを判断して処理をするってこと
ですよね。
 
jQueryのsetIntervalの代わりに利用した、NSTimerはほぼ定型なので省略。
→参考:google検索「NSTimer」
 
オブジェクトの位置はCGPointクラスで指定しなければならないようです。
そしてCGPointクラスを作成するのがCGPointMakeメソッド。
→参考:CGRect、CGPoint、CGSizeの真ん中あたり
 
で、実際にオブジェクトの位置を管理しているのがcenterプロパティ
類似したプロパティとしてframeやboundsがあるそうです。
→参考:UIViewのframeとboundsとcenter
→参考:iPhoneアプリ開発の虎の巻
 
実際に移動させている部分は以下の通り。
——————————————————
-(void) moveFunc:(NSTimer *)timer
{
 float myX = debugArea.center.x;
 float myY = debugArea.center.y;
 myX++;
 if(myX > 320) myX = 0.0;
 debugArea.center = CGPointMake(myX, myY);
}
——————————————————
jQueryのサンプルと異なり、右端にきたら左端に移動するようにしました。
細かい構文は、まだよく分かりませんが。今回はこんな感じです。
 
 
 

メモ

jQueryでの移動サンプルでは以下の様な修正をしました。
——————————————————
修正前→ $(“#moveArea”).mouseup(touchesEnded);
修正後→ $(document).mouseup(touchesEnded);
——————————————————
修正前のサンプルはmoveAreaの外でマウスアップしてしまうと、touchesEndedが実行されず
移動し続けてしまうため、ブラウザ上のどこでマウスアップしてもtouchesEndedしたのです。
 
このことを鑑みてxcodeの以下の部分を確認するとif文でmoveAreaかどうかを
判定しています。
——————————————————
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch *touch = [touches anyObject];
 if ( touch.view.tag == moveArea.tag ){
  [moveTimer invalidate];//—timerの停止
 }
}
——————————————————
だから同じようにmoveAreaの外でtouchesEndedすると、移動し続けてしまうのでは?
と思ったのですが、そうはなりませんでした。
 
私の理解としては、PCのclickイベントが最初にmousedownした要素を覚えており、
その要素上でmouseupしないとイベントが発生しないのに近い気がします。
つまり、上記の処理の意味は「moveAreaで発生したtouchesBeganが終わった時に」
という感じだと思います。
 
もし、このif文を外してしまうとmoveArea以外でで発生した場合も処理を実行してしまい
そのため作成していないmoveTimerを停止することになりプログラム上良くないのでしょう。
たぶん。
※moveTimerはmoveAreaがタップされた時にしか作成されない
 
 
 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


八 + = 10


*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>