UIGestureRecognizerが糞使えない理由
皆使ってる UIGestureRecognizer ですが、こいつで泣かされる人もわりと多いと思う。
UIGestureRecognizerについては、ググってくれればいい。
UIGestureRecognizerの派生クラスで以下のものがある。
UITapGestureRecognizer タップ
UIPinchGestureRecognizer ピンチインアウト主に拡大縮小
UIPanGestureRecognizer ドラッグ
UISwipeGestureRecognizer ページめくりやスクロール等のスワイプ
UIRotationGestureRecognizer 指2本で回転させる感じ
UILongPressGestureRecognizer 長押し
いわゆる、1~4本指スワイプ、2本指回転、長押しあたりを検出するクラスである。
こいつがほぼ使えない。
なぜかというと、touches{Began|Moved|Ended}との相性がとても悪い。
Gesture系のイベントが発生すると、touch系のイベントが発生しない。
これによって、touchesMovedを検出したいのに、swipeGestureが検出されるということが起こる。
あるいは、swipeGestureを検出したいのに、touchesBeganが発生するというようなことが起こる。
また、swipeGestureやLongPressGestureから、touchEndedへつなげるといったようなことができない。
例えば、単なる長押しならいいが、長押しのあとにスライドを検出したい場合や、
回転の後に、指離しを検出してなにかしたいという場合は、
UIGestureRecognizerでやろうとすると、複雑な実装になる。
つまり、回転、スワイプなどは、結局自前で作ってdelegateして使うということが一番簡単なので、
簡単なビューで即席的なものならありだが、それ以外の場面では、これらのクラスは極力使わないようにしたい。
touches{Began|Moved|Ended}だけでタッチ処理を実装するのが、今のところ一番いいと思う。
ResponderChainとDelegate
UIKitでプログラミングしていると、サブビュー(UIViewとその派生)が次々と増えていく。
ビューが重なりあった状態では、最も下層にあるビューが、FirstResponderとなる。
FirstResponderというのは、最初にイベントを受け取るオブジェクトのこと。
例えば、TextFieldにフォーカスがあってたら、TextFieldがFirstResponderである。
で、指でViewに対してタッチすると、touches{Began|Moved|Ended}の一連のイベントが発生するが、
このイベントというのは、FirstResponderがまず受け取る。
FirstResponderにてイベントハンドラが定義されている場合、実行される。
イベントハンドラが定義されていなければ、NextResponderがFirstResponderになる。
UIViewの場合は、その親ビューにイベントが渡される。
このように、次々とスーパービューへとイベントが渡されていく。
これをResponderChainという。
FirstResponderにイベントハンドラがあるが、
その親ビューや、そのさらに親ビューのイベントハンドラや関数を実行したい場合は
Delegateを使う。
Delegateは大体の場合が、非公式プロトコルというObj-Cの仕組みで実装する。
Javaでいうところの、Interfaceのような感じ。
コンパイル通るかわからないけど、簡単な例を示すと、だいたい次のような感じ。
View1が、View2の親ビュー。
View2でタッチしたイベントを、View1にdelegateする。
というわけで、はてな様、私にMac11インチくださったら、役立てますので宜しくお願いします。
touchDelegate.h
@protocol touchDelegate - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event @end
View1.m
#import "touchDelegate.h" @interface View1:UIViewControler <touchDelegate> { UILabel *label; } @end @implementation View1 - (void) viewDidLoad { UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100,100)]; view2.delegate = self; [self.view addSubView:view2]; } - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { label.text = @"aho"; } @end
View2.m
#import "touchDelegate.h" @interface View2:UIViewController <touchDelegate> { id delegate; } @end @property (nonatomic,retain)id delegate; @implementation View2 @synthesize delegate; - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { [delegate touchesBegan:touches withEvent:event]; } @end
MacBook Air 11インチ欲しい!
いちばんいいのをお願いします!
非公開ソースのインタフェースの数を調べる
ソースが公開されていないライブラリ、オブジェクトファイル(*a,*o)の呼び出されているAPI数を調べる。
次のスクリプトを実行させると、dにAPIの一覧がのる。
#!/bin/bash #呼び出し側のソース: find ${caller_path} -name "*.[oa]" | xargs nm | xargs cat > a grep "U " a > aa sort aa |xargs uniq > aaa #未解決シンボル一覧 cut -f 3- < aaa > aaaa #シンボル名だけ抜き出す #呼び出され側ソース: find ${callee_path} -name "*.[oa]" | xargs nm | xargs cat > b grep -v "U " b > bb sort bb | xargs uniq > bbb #解決シンボル一覧 cut -f 3- < bbb > bbbb #シンボル名だけ抜き出す cat aaaa bbbb > c #呼び出し側未解決シンボル、呼び出され側解決シンボルをつなげる sort cc | xargs uniq -u > ccc #解決されたシンボルは消える diff -c aaaa ccc | xargs grep "+ " > d #解決されたシンボルの一覧をdに出力する
Android(環境構築)
APR/1にXperiaをゲットし、今週月曜の会社の飲み会で、先輩に、
「そういうの買った人はAndroidのアプリを自作するでしょ」
とさらっと云われたので、密かに家で作るか。
ま、そんなのはどうでもいいことで、いつも通りメモ。
環境:
MacOS X(10.5.8)
JDK(1.5.0_20)
Eclipse(3.4.2)
Android SDK(1.6)
Android Development Toolkit(0.9.6v20)(Eclipseのプラグイン)
google API(?)
上記は、ここからゲット:
http://developer.android.com/sdk/index.html
bashrcに下記追加:
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
ANDROID_HOME=/Developer/android-sdk-mac_86-r4
PATH=$PATH:${ANDROID_HOME}/tools
まず、AndroidのシミュレータAVDを生成。
この引数のtargetは、googleSDKのIDに対応。
$ android create avd --target 2 --name aho1
Hello World までは以下のサイトが参考になった。
http://d.hatena.ne.jp/ynakajima/20090522
一人の開発の意識
一人で開発して、納期に間に合わせるために必要だと思うのは以下のこと。
・リソース
自分自身の全ての生きる時間をリソースとして考える。
生活のどれがリソースに対しどの程度のコストを払うかを考える。
あらかじめ、配分を決めておき、そこから大きく乖離するような配分にしない。
スケジュール、いつまでにどれを明確にする。
・優先順位
一人で開発し、期限がある以上、全部を実装することはできず、どれかは必ず捨てることになる。
機能やタスクは全て書き出して把握する。
機能やタスクの全てに優先順位があり、取捨選択の判断が必要。
まず最初に優先することは、最低限の動作。
・UIや機能は使い勝手良くシンプルにする。
多くの機能を盛り込むとバグがそれだけ増え、自分自身に跳ね返ってくる。
複雑で高コストな機能に着手するときは、効果がそれだけあるのかよく考え、
代替え手段などを一通り見比べ切り捨てることも必要。
複雑で高コストな機能は、一見便利だが、骨折り損なことが多いのでほとんど捨てることになる。
「イケメン人狼タウン」リリースしました
1ヶ月くらい、OpenSocialをぼちぼちとやってましたが、
昨日、「イケメン人狼タウン」というmixiアプリをリリースしました。
http://mixi.jp/view_appli.pl?id=9624
まだまだテスト段階ですが、遊んでくださる方を大絶賛募集しています。
忙しい方のために3日で進行する村と、通常の1日進行村の2つがあります。