2010年2月18日 (木)

何か実機用コンパイルでエラーが…

こんなエラーが表示されて先に勧めない…。

>Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain

何のトラブルも無く実行されている方も居るのに…

何が悪いの?

テスト的に作ったプロジェクトも駄目だった…。

承認作業を間違えた?

取り合えず、承認作業を最初っからやり直してみる。

一番怖かったのは、『iPhone Developer Proogram』の
『Certificates』を削除するくだり…。

ライセンスが無効になる事は、無いだろうと思ったけど…
『Recoke』をクリックすると
「関連付けされたもろもろが無効になるよ」
的なメッセージが表示された。

取り合えず実行…。

リンクが切れたかもしれないが登録した内容は、
そのまま残っているみたい。
後で要調整って事なのか?

再度『キーチェーンアクセス』で機体承認作成からやってみる。
『環境設定』の『証明書』内の項目が2つとも『切』に
なっているのを確認。

『認証局に証明書を要求…』で『ユーザーのメールアドレス』は
取り合えず登録したものを記入。

でも『コモンネーム』って何?

最初は、その機材のログイン名が入っているからって何も考えず
『続ける』ってやったけど…

『HowTo』を見るとどうも登録した名前が入るらしい。

英語っぽく『FirstName LastName』で入れてみた。

で『CertificateSigningRequest.certSigningRequest』を
作り直して改めて『Certificates』作った。
で、『developer_identity.cer』をダウンロードして
『キーチェーンアクセス』に登録したら…
今まで『自分の証明書』って所に入らなかったのが入った!

って、これが原因か?

詰まったら『HowTo』を見直そう…。(汗)

なお、最終的に『Certificates』の作り直しでのペナルティは、
『Provisioning 』の『Certificates』のリンクが切れるだけだった。
リンクし直してダウンロードし直して登録しなおせばOK。

後は、『Xcode』の設定エラーだけで一個一個潰していって
無事実機で実行できた…。

めでたしめでたし!

PS.

もっと簡単に設定できるようにして欲しい!
って勝手に思うぞ!

| | コメント (2) | トラックバック (0)

2010年2月13日 (土)

タップのインターバルってどのぐらい?

前回の『タップ数でダイレクトにセレクトしたい…』で
タップインターバルを0.5秒としたが…
実際に0.5秒と明確に書いてあるものが無い…。(汗)

アップルのヘルプにも書いてないっぽい。

でもインターバルが分からん事には、ディレイの設定ができん…。

こっちには、0.5秒だとある。

Double Tap Detection

説明に
「ダブルタップインターバルのデフォルトは、0.5でしょう。
0.2では、早すぎるし1.0では、遅すぎる。」
みたいな事が書いてある。

本当か?

それをどうしたら確認できる?

ゴロゴロ…

ゴロゴロ…

ゴロゴロ…

ピコン♪

タップをプログラムで発生させどのタイミングで
ダブルタップになるか測定する!

ってのは、どうだろう?

まずは、タッチをどう発生させるか…?

色々、大変そうなのでやめ…。(汗)

もっと簡単な方法は無いかなぁ~?

じゃあ、アトランダムにタップを行い
それを計測するのはどうだろう?

これなら簡単に出来そうだ…。

『touchesBegan』に来た時に時間を取得する。
次の『touchesBegan』に来た時の時間と比較する。
タップと認識している、していない時の時間を
ストックしていって最終的にこの辺りと
絞り込む処理を作成してみよう。

『GetTickCount』みたいな関数が無い…!?

タイマースレッドを立ち上げて自前でカウンターを作るのか!?

精度に難がありそうだけど…
取り合えずやってみる。

[TapTestViewController.h]
- ( void )touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event;

[TapTestViewController.m]
...
NSTimer            *timer;
unsigned int tmerCount;
-(void)timerFunc
{
    tmerCount++;
}
...
- (void)viewDidLoad {
    timer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector( timerFunc ) userInfo:nil repeats:YES];
    [super viewDidLoad];
}
...
//******************************************************************************
//    タッチ処理
//******************************************************************************
//**************************************
//    Work
//**************************************
unsigned int    countBackup;
unsigned int    onTap;
unsigned int    noTap    = 10000;
//**************************************
//    touchesBegan
//**************************************
- ( void )touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event
{
    unsigned int    between;
    int                tap;
    UITouch            *touch        = [touches anyObject];

    between        = tmerCount - countBackup;
    countBackup    = tmerCount;
    tap            = [touch tapCount];

    if( tap > 1 )
    {// 連続タップ
        if( onTap < between )
            onTap    = between;
    } else
    {// 非連続タップ
        if( noTap > between )
            noTap    = between;
    }

    char            string[512];
    sprintf( string, "taps:%2d\nget sec:%4d\non sec:%4d\nno sec:%4d", tap, between, onTap, noTap );
    [infoTextView setText:[NSString stringWithUTF8String:string] ];
}

//******************************************************************************
//    End
//******************************************************************************

で試しに動かしてみた…。

※シミュレータでの動作だけどね…。

でこんな感じになった。

20100211001

あれ?

0.6秒を連続タップと認識するのか?

でも0.4秒をシングルタップって認識する?

もしかしてタップインターバルが変動している?

連続タップした時の間から次のタップインターバルを
算出しているのならインターバルの定数が無いのもうなずける。

早く連続タップすると次のシングルタップ判定の
インターバルが0.5を切るみたいだし…。

本当にそう言う処理をしているか謎だけどね。

単に精度が悪いって事もあるけどね…。

実記じゃなくシミュレータってのも多分に影響しているだろうし。

でも個人差をこう言う形で吸収しているのなら凄いかも…。

音楽ゲームやタイミングゲームでタップを主体にした
ものは、誤作動するかもしれないのでこの方式は取らない方が無難そうだ。

でもタップインターバルは、0.5秒辺りに収束するっぽいので
0.5秒で良いんじゃない?

で、結論は…

0.5秒って事にしよう♪

てす…。

PS.

試しにタップ回数ごとの時間を取ってみた。

20100211002

他にソースをこんな感じに直して
ダブルタップ限定で時間を取得してみた。

    if( tap == 2 )
    {// 連続タップ
        if( onTap < between )
            onTap    = between;
    } else
    if( tap == 1 )
    {// 非連続タップ
        if( noTap > between )
            noTap    = between;
    }

20100211003

まあ、0.5秒ぐらいが適当かと思う。

まあ、処理を間違えてないければ…

だけどね…。(汗)

サンプルは、こちら。

「TapTest.zip」をダウンロード

| | コメント (0) | トラックバック (0)

2010年2月12日 (金)

タップ数でダイレクトにセレクトしたい…

タップ数で機能を選択でできねぇ~?

ってのたまわれた…。

タップ1回(もしくはタッチ)ならマップ移動で…
タップ2回ならショットで…
タップ3回なら…。
…etc…

どうしたら良いのかね?

途中、ショットとか手を放したら処理として成立するものがあると
上手くいかない…。

最終的に『何回タップしました』って形に結果が来ないと困る…。

取り合えずアップルのヘルプをチョコチョコっと見てみた…。

タップ処理でレスポンダオブジェクトってのは難しいそうだ…
うんぬんかんぬんぐらいしか書いていない…。

もうチョット詳しく書いて欲しいぞ!

サンプルによるとタップしたらスレッドを作って
次のタップが来るかもしれない時間を待つ。
タップが来たら前のスレッドを削除し、そして新しい待ちスレッドを立てる。
タップが来なかったらそのスレッドの処理を行う方法。

でもダブルタップのディレイって幾つなんかね?

探しても見付からないんですけど…。

設定項目も無さそうなので固定値かと思われるのだが…

なんかの関数で得られるのかね?

こっちに結構良いサンプルを見付けた。

Handling Double Taps

ちなみに本のサンプルにも似たようなものがあったよ。

これを細工して幾らでもタップカウントが出来るようにしてみた…。

『View-base Application』でプロジェクトを作って…

[TapsViewController.h]
//--------------------------------------
- ( void )touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event;
- ( void )touchesMoved:( NSSet* )touches withEvent:( UIEvent* )event;
- ( void )touchesEnded:( NSSet* )touches withEvent:( UIEvent* )event;
- ( void )touchesCancelled:( NSSet* )touches withEvent:( UIEvent* )event;

[TapsViewController.m]
//******************************************************************************
//    タッチ処理
//******************************************************************************
//**************************************
//    Work
//**************************************
#define        TAP_INTERVAL        0.5
//--------------------------------------
BOOL            touchStartFlag;            // タッチフラグ
BOOL            touchFlag;                // タッチフラグ
int                touchTaps;                // タップ回数
CGPoint            touchPoint;                // タッチ位置
CGPoint            touchMove;                // タッチ移動量
//**************************************
//    touchInfo
//**************************************
- ( void ) touchInfo
{
    char            string[512];
    int                t, m;
    float            x, y;

    if( !touchFlag )
    {
        t    = 0;
        x    = 0;
        y    = 0;
    } else
    {
        t    = touchTaps;
        x    = touchMove.x;
        y    = touchMove.y;
    }
    m    = touchStartFlag;

    sprintf( string, "taps:%2d\nmx:%f\nmy:%f\nmode:%d", t, x, y, m );
    [infoTextView setText:[NSString stringWithUTF8String:string] ];
}

//**************************************
//    touchesParameterGet
//**************************************
- ( void ) touchesParameterGet:( NSSet* )touches
{
    static CGPoint    pointBackup;
    UITouch            *touch    = [touches anyObject];

    touchPoint    = [touch locationInView:self.view];
    switch( touch.phase )
    {
    case UITouchPhaseBegan:
        touchStartFlag    = TRUE;
        pointBackup        = touchPoint;
        // …何か処理…
        break;

    case UITouchPhaseEnded:
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector( touchTapMethod ) object:nil];
        touchFlag    = FALSE;
        touchStartFlag    = FALSE;
        // …何か処理…
        break;

    default:
        if( !touchFlag )
            return;
        break;

    case UITouchPhaseCancelled:
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector( touchTapMethod ) object:nil];
        touchFlag        = FALSE;
        touchStartFlag    = FALSE;
        return;
    }

    touchMove.x    = touchPoint.x - pointBackup.x;
    touchMove.y    = -touchPoint.y + pointBackup.y;

    // …何か処理…
    [self touchInfo];
}

//**************************************
//   
//**************************************
- ( void ) touchTapMethod
{
    touchFlag    = TRUE;
    [self touchInfo];
}

//**************************************
//    touchesBegan
//**************************************
- ( void )touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event
{
    UITouch            *touch        = [touches anyObject];

    touchTaps    = [touch tapCount];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector( touchTapMethod ) object:nil];
    [self performSelector:@selector( touchTapMethod ) withObject:nil afterDelay:TAP_INTERVAL];

    [self touchesParameterGet:touches];
}

//**************************************
//    touchesMoved
//**************************************
- ( void ) touchesMoved:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches];
}

//**************************************
//    touchesEnded
//**************************************
- ( void ) touchesEnded:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches];
}

//**************************************
//    touchesCancelled
//    ※電話の着信などの強制割り込み時に呼ばれます。
//**************************************
- ( void ) touchesCancelled:( NSSet* )touches withEvent:( UIEvent* )event;
{
    [self touchesParameterGet:touches];
}

//******************************************************************************
//    End
//******************************************************************************

分かりきっていると思うけどレスポンスは、悪くなる。

なので入力状態がユーザーに分かるようにする表示の工夫か
もしくは、0.5秒間タッチさせたくなる演出上の工夫が必要かもしれない。

例えば、タップすると『1タップ・2タップ』などタップ数に合わせて
吹き出しをズームさせて注視させるなどが考えられる。
ズームに0.4秒使えばタップ待ちが気にならないのでは?

タップするたびに項目が浮かび上がるでも良いんじゃないだろうか?

まあ、処理の一つとして用意しておくと何かの時に助かるかも…。

って訳でメモ、メモ♪

PS.

自分が困った時用にサンプルもアップしておこう…。(笑)

20100211

「Taps.zip」をダウンロード

| | コメント (0) | トラックバック (0)

2010年2月 6日 (土)

『キーチェーンアクセス』で証明書が作れません!(泣)

『iPhone SDK』で『キーチェーンアクセス』ってのが必要らしい…。

1.『アプリケーション』から『ユーティリティ>キーチェーンアクセス』で
  『キーチェーンアクセス』を起動。

2.『キーチェーンアクセス>証明書アシスタント>認証局に証明書を要求...』で
  『CertificateSigningRequest.certSigningRequest』というファイルができる。

らしいのですが…

出来ません…。(泣)

『Mac OS X バージョン 10.5.8』だからか!?

何てことは、無いはず!

何が悪いのだろう…。

出来ないのなら『○○が××なので出来ませんでした!』ぐらい出せ!

などと思いながら『キーチェーンアクセス>環境設定...』を開いてみる。

『証明書』のボタンを押すと…
・オンライン証明書状況プロトコル(OCSP):切
・証明書失効リスト(CRL):切
となっている。

もしかしてこれか?

多分どっかにある『認証局』って所にアクセスする必要があるんでないかえ?

取り合えず、両方とも『切』から『可能な場合に適用』に変更する。

念のため『優先順位:OCSP』としておく…。

おお!

『承認アシスタント』で『鍵ペア情報を指定』が出てきた!

その後、手順通りにやったら出来たよ!

必要なら必要って言えよ!(怒)

と思った…。

でも、その後にアクテベートして『iPhone Developer Program』の
『iPhone Developer Program Portal』内の『Certificates』の
『How To』を見たら…

『off』にしろって書いてあるっぽい…?

試しに『off』にしてやってみると手順通りに作成できた…。

ええ?

これって…

もしかしたら何かで既に証明書を作成してある事を期待していないか?

既にある証明書を使え!

重複して証明書を幾つも作るな!

って感じなのかもしれない…。

だからわざわざ『off』って書いてあるのかも…。

でも証明書を持ってない時も書いて欲しいよ!

ちなみに何か見落としていて書いてあることが
間違っているかもしれないので
その辺は、加味してね…。

なお、その後の登録の『How To』を見たけど…
HPが更新されているのか微妙に言い回しが変わっていて…

難儀しました!(汗)

例えば『Add Certificate -> Request Certificate』だったり…
『Choose File -> 選択…』だったり…
って何故かそこだけ日本語!?

あと『WWDR』を『キーチェーンアクセス』の
何処にインストールするかが書いてなかったり…。

デフォルトだと『ログイン』だからここに入れるのかな?

まあ、別な所にインストールのし直しも削除もできるるので
後で直せば良いか…。

とは言え…

初心者が迷わないようきちんと書けよ!

なんて思いました…。

ちなみに愚痴です…。

| | コメント (0) | トラックバック (0)

2010年2月 5日 (金)

『iPhone』のマルチタッチってどうやったら良いのかね?

マップの拡大縮小や移動にマルチタッチは、どうよ?

ってな話があって…

何となくマルチタッチに対応…。

何となくざっくりソース…。

[EAGLView.h]
//--------------------------------------
- ( void )touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event;
- ( void )touchesMoved:( NSSet* )touches withEvent:( UIEvent* )event;
- ( void )touchesEnded:( NSSet* )touches withEvent:( UIEvent* )event;
- ( void )touchesCancelled:( NSSet* )touches withEvent:( UIEvent* )event;

[EAGLView.m]
- ( id ) initWithCoder:( NSCoder* )coder
{
    ...
    // ※マルチタッチに対応します。
    self.multipleTouchEnabled    = YES;
    ...
}

//******************************************************************************
//    タッチ処理
//******************************************************************************
//**************************************
//    Work
//**************************************
BOOL            touchFlag;                // タッチフラグ
CGPoint            touchPoint;                // タッチ位置
CGPoint            touchMove;                // タッチ移動量
//--------------------------------------
BOOL            touchMultiFlag;            // マルチタッチフラグ
BOOL            touchMultiLock;            // マルチタッチフラグ
CGPoint            touchMultiCenter;        // マルチタッチ中心位置
float            touchMultiLength;        // マルチタッチ距離
CGPoint            touchMultiMove;            // マルチタッチ移動量
float            touchMultiRotate;        // マルチタッチ回転量
//**************************************
//    touchesMultiParameterGet
//**************************************
- ( void ) touchesMultiParameterGet:( NSSet* )touches
{
    static float    lengthBase, rotateBase;
    static CGPoint    centerBase;
    CGPoint            point0, point1, center;
    float            length, rotate, x, y;
    UITouch            *touch;
    NSArray            *array;

    touch        = [touches anyObject];
    array        = [touches allObjects];
    point0        = [ [array objectAtIndex:0]locationInView: self];
    point1        = [ [array objectAtIndex:1]locationInView: self];
    x            = point0.x - point1.x;
    y            = point0.y - point1.y;
    length        = sqrt( x * x + y * y );
    center.x    = x / 2 + point1.x;
    center.y    = y / 2 + point1.y;
    rotate        = atan2( y, x );

    // 初期化
    // ※『touchMultiFlag』で判断しているので注意
    if( !touchMultiFlag )
    {
        lengthBase        = length;
        centerBase        = center;
        rotateBase        = rotate;
        touchFlag        = FALSE;
        touchMultiLock    =
        touchMultiFlag    = TRUE;
    }

    touchMultiLength    = length - lengthBase;
    touchMultiCenter    = center;
    touchMultiRotate    = rotate - rotateBase;
    touchMultiMove.x    = center.x - centerBase.x;
    touchMultiMove.y    = - center.y + centerBase.y;

    printf( "l:%f - r:%f - mx:%f - my:%f\n", touchMultiLength, touchMultiRotate, touchMultiMove.x, touchMultiMove.y );
}

//**************************************
//    touchesParameterGet
//**************************************
- ( void ) touchesParameterGet:( NSSet* )touches
{
    static CGPoint    pointBackup;
    UITouch            *touch    = [touches anyObject];

    // マルチタッチ起動のチェック
    // ※『[touches count]>1』は、『UITouchPhaseBegan』だけでなく『UITouchPhaseMoved』中にも来ます。
    // ※そのためフラグとの組み合わせて起動をチェックしています。
    if( !touchMultiFlag && ( [touches count] > 1 ) )
    {
        [self touchesMultiParameterGet:touches];
        // …何か処理…
    }

    // マルチタッチ処理
    if( touchMultiFlag )
    {
        if( ( touch.phase == UITouchPhaseEnded ) || ( touch.phase == UITouchPhaseCancelled ) )
        {
            touchMultiLock    =
            touchMultiFlag    = FALSE;
            return;
        }
        if( [touches count] <= 1 )
        {
            touchMultiFlag    = FALSE;
            return;
        }
        [self touchesMultiParameterGet:touches];
        // …何か処理…
        return;
    }

    if( touchMultiLock )
        return;

    // シングルタッチ処理
    touchPoint    = [touch locationInView:self];

    switch( touch.phase )
    {
    case UITouchPhaseBegan:
        touchFlag    = TRUE;
        pointBackup    = touchPoint;
        // …何か処理…
        break;

    case UITouchPhaseEnded:
        touchFlag    = FALSE;
        // …何か処理…
        break;

    default:
        if( !touchFlag )
            return;
        break;

    case UITouchPhaseCancelled:
        touchFlag    = FALSE;
        return;
    }

    touchMove.x    = touchPoint.x - pointBackup.x;
    touchMove.y    = -touchPoint.y + pointBackup.y;

    printf( "mx:%f - my:%f\n", touchMove.x, touchMove.y );

    // …何か処理…
}
//**************************************
//    touchesBegan
//**************************************
- ( void ) touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches];
}

//**************************************
//    touchesMoved
//**************************************
- ( void ) touchesMoved:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches];
}

//**************************************
//    touchesEnded
//**************************************
- ( void ) touchesEnded:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches];
}

//**************************************
//    touchesCancelled
//    ※電話の着信などの強制割り込み時に呼ばれます。
//**************************************
- ( void ) touchesCancelled:( NSSet* )touches withEvent:( UIEvent* )event;
{
    [self touchesParameterGet:touches];
}

//******************************************************************************
//    End
//******************************************************************************

※『touchMultiLock』は、タッチする指を二本から一本、一本から二本と変えた時に
初期情報を初期化したいので『touchMultiFlag = FALSE』にします。
このとき『touchMultiFlag = touchFlag = FALSE』の状態が発生します。
さらにタッチする時に『UITouchBegan』まで発生します。
この時『[touches count]<=1』でシングルタッチ処理に流れてしまいます。
『touchMultiLock』でシングルタッチ処理へ流れるのを回避します。

ちなみに二本指の移動は、『iPhoneシミュレーター』で
『option + shift + マウス』でできるそうだ。

こちらに書いてあって助かった…。

[iPhone] iPhone シュミレータでマルチタッチを平行に動かす方法

有難うございます…。

>if( [touches count] == [ [event touchesForView:self] count] )

で最後の指が離れたのをチェックしろってのもあるけど…

3Dエディタのようにウインドウが個別にあってそのウインドウ内の
表示を個別に拡大縮小するのなら必要なのかも?

多分、これには必要無いと思う…。

取り合えず、これでOK!

と思う一方で…

駄目かも…。

あんま調べてないんで…。(汗)

何かバグ見付けたら教えてください…。>誰か…

※シミュレータでしか動作を確認していないんで実機だと駄目かも…。(汗)

PS.

ちなみに、これを作った後に『iPhone OS Reference Library』の
『Touches』ってサンプル見たけど…
全く異なる方式なので参考にならん…。

一応こちらに何となくテストプログラムをアップしてみた…。

「touch.zip」をダウンロード

操作は、こんな感じ…。
■マウスドラッグ
・移動
■option + マウスドラッグ
・拡大縮小
・回転
■option + shift + マウスドラッグ
・移動

詳しくは、ソースを見てちょ…。

2010年2月16日追記----------------

実機で試して見たらバグバグだった…。(汗)

二本以上になったら「event」から情報を得ないと駄目!

って事がわかった…。

でソースの書き換え…。

//******************************************************************************
//    タッチ処理
//******************************************************************************
//**************************************
//    Work
//**************************************
extern    float            scale;
extern    float            rotate;
extern    CGPoint            position;
//--------------------------------------
#define        PI                3.1415926535897932384626433832795
#define        SCALE_RATE        120
#define        MOVE_RATE        80
//--------------------------------------
BOOL            touchFlag;                // タッチフラグ
//--------------------------------------
BOOL            touchSingleFlag;        // シングルタッチフラグ
CGPoint            touchSinglePoint;        // シングルタッチ位置
CGPoint            touchSingleMove;        // シングルタッチ移動量
//--------------------------------------
BOOL            touchMultiFlag;            // マルチタッチフラグ
BOOL            touchMultiLock;            // マルチタッチロックフラグ
CGPoint            touchMultiCenter;        // マルチタッチ中心位置
float            touchMultiLength;        // マルチタッチ距離
CGPoint            touchMultiMove;            // マルチタッチ移動量
float            touchMultiRotate;        // マルチタッチ回転量
//**************************************
//    touchesMultiParameterGet
//**************************************
- ( void ) touchesMultiParameterGet:( UIEvent* )event
{
    static float    lengthBase, rotateBase;
    static CGPoint    centerBase;
    CGPoint            point0, point1, center;
    float            length, rotate, x, y;
    NSArray            *array;

    array        = [[event touchesForView:self] allObjects];
    point0        = [[array objectAtIndex:0]locationInView:self];
    point1        = [[array objectAtIndex:1]locationInView:self];
    x            = point0.x - point1.x;
    y            = point0.y - point1.y;
    length        = sqrt( x * x + y * y );
    center.x    = x / 2 + point1.x;
    center.y    = y / 2 + point1.y;
    rotate        = atan2( y, x );

    // 初期化(※『touchMultiFlag』で判断しているので注意)
    if( !touchMultiFlag )
    {
        lengthBase        = length;
        centerBase        = center;
        rotateBase        = rotate;
        touchSingleFlag    = FALSE;
        touchMultiLock    =
        touchMultiFlag    = TRUE;
    }

    touchMultiLength    = length - lengthBase;
    touchMultiCenter    = center;
    touchMultiRotate    = rotate - rotateBase;
    touchMultiMove.x    = center.x - centerBase.x;
    touchMultiMove.y    = - center.y + centerBase.y;
}
//**************************************
//    touchesParameterGet
//**************************************
- ( void ) touchesParameterGet:( NSSet* )touches event:( UIEvent* )event
{
    static float    scaleBackup, rotateBackup;
    static CGPoint    positionBackup;
    static CGPoint    pointBackup;
    UITouch            *touch    = [touches anyObject];

    // キャンセル時の処理
    if( touch.phase == UITouchPhaseCancelled )
    {
        touchFlag        =
        touchSingleFlag    =
        touchMultiLock    =
        touchMultiFlag    = FALSE;
        return;
    }

    // マルチタッチ起動のチェック
    // ※『[touches count]>1』は、『UITouchPhaseBegan』だけでなく『UITouchPhaseMoved』中にも来ます。
    // ※そのためフラグとの組み合わせて起動をチェックしています。
    if( !touchMultiFlag && ( [[event touchesForView:self] count] > 1 ) )
    {
        [self touchesMultiParameterGet:event];
        scaleBackup        = scale;
        rotateBackup    = rotate;
        positionBackup    = position;
    }

    // マルチタッチ解除
    if( touchMultiLock && ( touch.phase == UITouchPhaseEnded ) && ( [touches count] == [[event touchesForView:self] count] ) )
    {
        touchFlag        =
        touchSingleFlag    =
        touchMultiLock    =
        touchMultiFlag    = FALSE;
        return;
    }

    // マルチタッチ処理
    if( touchMultiFlag )
    {
        if( [touches count] <= 1 )
        {
            touchMultiFlag    = FALSE;
            return;
        }
        [self touchesMultiParameterGet:event];
        scale    = scaleBackup + touchMultiLength / SCALE_RATE;
        rotate    = rotateBackup - touchMultiRotate * 180 / PI;
        position.x    = positionBackup.x + touchMultiMove.x / MOVE_RATE;
        position.y    = positionBackup.y + touchMultiMove.y / MOVE_RATE;
        return;
    }

    if( touchMultiLock )
        return;

    // シングルタッチ処理
    touchSinglePoint    = [touch locationInView:self];
    switch( touch.phase )
    {
    case UITouchPhaseBegan:
        touchFlag        =
        touchSingleFlag    = TRUE;
        pointBackup        = touchSinglePoint;
        positionBackup    = position;
        break;

    case UITouchPhaseEnded:
        touchFlag        =
        touchSingleFlag    = FALSE;
        break;

    default:
        if( !touchFlag )
            return;
        break;
    }

    touchSingleMove.x    = touchSinglePoint.x - pointBackup.x;
    touchSingleMove.y    = -touchSinglePoint.y + pointBackup.y;
    position.x    = positionBackup.x + touchSingleMove.x / MOVE_RATE;
    position.y    = positionBackup.y + touchSingleMove.y / MOVE_RATE;
}
//**************************************
//    touchesBegan
//**************************************
- ( void ) touchesBegan:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches event:event];
}
//**************************************
//    touchesMoved
//**************************************
- ( void ) touchesMoved:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches event:event];
}
//**************************************
//    touchesEnded
//**************************************
- ( void ) touchesEnded:( NSSet* )touches withEvent:( UIEvent* )event
{
    [self touchesParameterGet:touches event:event];
}
//**************************************
//    touchesCancelled
//    ※電話の着信などの強制割り込み時に呼ばれます。
//**************************************
- ( void ) touchesCancelled:( NSSet* )touches withEvent:( UIEvent* )event;
{
    [self touchesParameterGet:touches event:event];
}
//******************************************************************************
//    End
//******************************************************************************


よもや、クソみそに言った「[[event touchesForView:self] count]」…。
これがキーワードだったとは…。

「touch-new.lzh」をダウンロード

| | コメント (4) | トラックバック (0)

2010年1月18日 (月)

『iPhone』で上部ステータスを消してもタッチ範囲が残っているよ…

『iPhone』で『status bar is initially hidden』を設定すると
上部ステータスを非表示にすることが出来る。

でも、非表示にしてもタッチ範囲は残っていると見えて
その部分でタッチが出来なかったりする…。

全画面でタッチを行うアプリをやっている気が付いた…。

重ならないようにボタンを配置した場合や、
大雑把なドラッグのチェックでは
問題が無いので気が付かなかった…。

さらにドラッグで画面外まで行くと『touchesEnded』に
なるはずなのにステータスバーの所では
かなり異常な状態が発生する。

例えば…

1.ステータスバーの領域内でタッチ開始。
  でも『touchesBegan』は、来ない。
2.下へドラッグして領域を出る。
  『touchesBegan』が来て処理開始。
  『touchesMoved』にも来る。
3.上へドラッグして領域に入る。
  領域内は、『touchesMoved』が来ない。
4.領域内で手を離すと『touchesEnded』が来ない。

つまり、処理が完結しない…。

とっても困る!

じゃあ、この範囲はどうやって『disable』にすれば良いんだ?

って事になる…。

あるいは、表示したままにするか…。

取り敢えず以下のフラグを設定し
半透明にすると処理上破綻しないのを確認した。
>[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;
もしくは、『plist』に以下の設定を行う。
『Status bar style : transparent black style(alph of 0.5)』

あれ?
この設定ってアプリケーション終了しても戻らない?
自前でデフォルトに戻す必要があるっぽい…。(笑)

色々調べていくうちに
『status bar is initially hidden』と
>[UIApplication sharedApplication].statusBarHidden = YES;
は、同じではない事に気が付いた。
と言うのは、フラグの変更だけでは、以下の関数で得られる
ステータスバーの範囲指定が更新されないのだ。
>CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
多分こっちを使う方が良いのではないかと思う。
>[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];

出し入れする訳では無いのなら
『status bar is initially hidden』を使うのが吉だと思われる。

色々調べていくうちに
アプローチが間違えているんじゃないかと思い始めた…。

タッチスクリーンのタッチ範囲は、
1.320x480ドットの全体範囲。
2.全体範囲より優先順位の高い
  320x20ドットのステータス範囲。

と考えていたのだが…
新たにもう一つの考え方が思い付いた。
1.320x20ドットのステータス範囲。
2.320x460ドットの全体範囲。
 ※ドラッグでステータスと全体のつなぎの部分で
 特殊処理を行っている。

となるとステータスをいくらいじっても解決しない訳だ…。

と思っていたら、海外でも問題になっていた…。

『iphone status bar hidden touch』をキーワードにすると
「上手くいかないんですが…」的な質問をしている。
そこにあるコメントをみるとみんな引っかかっているのが分かる。

で、色々眺めていくと…
「実機では、正常に動くのでシミュレーターのバグ」と
結論付けている。

すみません…
実機無いんで…
確認できなかったりして…。(汗)

実機が、来たから確認してみよう…。

| | コメント (0) | トラックバック (0)

2010年1月12日 (火)

『iPhone』のテクスチャーの色の干渉ってどのぐらい?

アンチエイリアスをかけると絵のギザギザ感が取れるのだが
隣のドットの色が干渉してしまう。

まあ、そう言う機能なので当たり前なのだが…。

でも、一枚のテクスチャーに複数の絵をまとめて
切り出して使用したい場合には…
堺目のドットは、干渉をして欲しくない訳で…

と相反する内容が成立して欲しいなど
かなり身勝手な事を考えています。

ま、簡単に言うと干渉する範囲を探して
その範囲を緩衝領域としようと言うもの。

つまり表示しない範囲はどのぐらいか?

という事です…。

処理上、干渉は1ドットは超えないものと思います。

なので0.何ドット分が干渉範囲なのか?

つまり…

表示しない幅を『1.0,0.9, ... 0.1, 0.0』ドットと変化させて行き
大丈夫そうな所を探してみます。

このあたりは、実際に見てみないと分からないので…
組み込んで動かしてみます。

※今回面倒なのでソースは、省略!※

拡大縮小回転なんかすると干渉が見えたりします。

どうやら0.5ドットぐらいが干渉幅のようです。

そうすると1024ドットテクスチャーの緩衝領域は
『0.5/1024=0.00048828125』となります。

テクスチャーのドットサイズに依存するので
毎回値を算出する必要がありそうです。

結論!

半ドット分を緩衝幅とすると吉!

多分…。

こう言う場合、極端な状態を表示すると良く分かったりします。

試しに2x2ドットテクスチャーを表示してみました。
思いっきり融けています…。(笑)

何となく絵にするとこんな感じ…。

Image02560

しかし外側は、干渉が現れていません。

ならば、4x4ドットテクスチャーだと…
大体半ドットまで融けているのを確認できました。

何となく絵にするとこんな感じ…。

Image02561

これも外側は、干渉が現れていません。

この考え方は、他のアンチエイリアスにも利用可能っぽいので
メモメモ…。

| | コメント (0) | トラックバック (0)

2009年12月27日 (日)

『CFURLRef path』を簡単に文字列にしたいのだが…

『iPhone』のアプリケーションをでファイルのアクセスエラーを
『printf』で出力したい!

なんて思った…。

- ( id )initWithContents:( CFURLRef )path
{
    if( AudioServicesCreateSystemSoundID( path, &soundID ) != kAudioServicesNoError )
    {
        NSLog( @"erroe path: %@", path );
    }
}

で、ログ出るけど…

『printf』が好きなんじゃい!

結構便利だしね。

じゃあどうするか…

『CFURLRef path』から直接文字列は、取れないっぽい…。

『CFStringRef』までコンバートしてさらに
メモリを確保して文字列をコピーするのに
『CFStringGetCString』を使うのを見かけるが…

こんな奴…

- ( id )initWithContents:( CFURLRef )path
{
    /* 省略! */
    CFStringRef    a    = CFURLGetString( path );
    int            l    = CFStringGetLength( a ) + 1;
    char        *s    = ( char* )malloc( l );
    CFStringGetCString( a, s, l, kCFStringEncodingUTF8 );
    printf( "erroe path: %s\n", s );
    free( s );
}

でも…

もっと直接的に頂きたい!

もっと簡便に頂きたい!

もっと楽に頂きたい!

でツラツラ探していくと…。

どうやら『CFStringRef』までコンバートすれば、何とか成っぽい。

と言うのも『CFStringRef』は、『NSString』にキャストできるっぽい。

で、さらに『cString』で…

もとい『UTF8String』で文字列を直接引っ張り出せるっぽい…。

で、やってみた。

- ( id )initWithContents:( CFURLRef )path
{
    /* 省略! */
    printf( "erroe path: %s\n", [( NSString* )CFURLGetString( path ) UTF8String] );
}

おお!

出来たじゃん!

もしかしたら、当たり前なのかもしれないけど…

まだまだ初心者なんで…。

永遠の初心者…

って駄目ですか?

| | コメント (0) | トラックバック (0)

2009年10月14日 (水)

『Tab Bar Controller』で画像を設定できないよ?

『iPhone』でタブバーに挑戦中に問題発生。

タブバーに名称を設定できるのだが…
画像が設定できない。

『MainWindow.xib』をダブルクリックして『Interface Builder』を起動。
『Tab Bar Controller』をダブルクリックして『Tab Bar Controller』を表示。
表示されたレイアウトの中で『First』ボタンを選択すると
『Tab Bar Item Attributes』を選択できる。
この中で『Tab Bar Item』の『Identifier』を『Custom』から
他の物にすると画像と名称が一緒に設定される。

しかし『Custom』だと、その下の『Bar Item』で
『Title』を設定すれば名称は変更できるのだが
『Image』を変更しても『四角の何か』が表示されるだけ…。

ここに設定される画像は、何らかの細工が必要のだろうか?

しかし、マックの中には使える画像があるのでは?

何て思ってそれらしい画像を漁ってみた。

そしたら
Macintosh HD\Developer\Applications\Dashcode.app\Contents\Frameworks\CYKit.framework\Resources\Parts\CallButton.part\callGlyph.png
が何か良い感じに表示される。

よくよく調べてみると白と抜きだけの画像だ。

ああ、なるほど!

タブバーに設定できる画像は抜きの有る無しで表示をするんだ。

この時、色は完全に無視される…。(汗)

従って抜きが無い画像では『四角い何か』になるのか。

ついでに大きさなども調べてみると…
横幅は、幅がある分大きく出来るようだが
縦は、32ドットでスッパリ切られてしまう。

最終的に分かったフォーマットは、
基本32x32ドット。
PNGで抜き無しと抜き有りだけの画像となるようだ…。

チョット躓きましたよ。

参考までに画像をアップしてみる…。

ヒントになった『callGlyph.png』

Callglyph_2

自分で試しに作ってみた画像『test.png』

Test_2

『iPhone』上では、色が無視されているのが分かる。

Iphoneimage

こう言うのってもしかして本に書いてあるのかな?

オライリーの本でも買わなくちゃ駄目かな?

ってか買え!って声が聞こえそう…。(汗)

| | コメント (0) | トラックバック (0)

2009年10月 8日 (木)

『UIActionSheet』を使う時にチョットはまった…。

『iPhone』のプログラミングしていたら…
『UIActionSheet』の所でチョットはまった…。

最終的に分かった事は、プロジェクトを
『Windows-based Application』で作ったのが原因らしい…。

『View-based Application』で作った場合以下のプログラム動作する。

- (IBAction)pushDoButton:(id)sender {
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"やるの?" delegate:self cancelButtonTitle:@"やめる" destructiveButtonTitle:@"やる" otherButtonTitles:nil];
    [actionSheet showInView:self.view];
    [actionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(buttonIndex!=0) {
        // 『やる』処理
    }
}

所が『Windows-based Application』だと、
まず『[actionSheet showInView:self.view];』が
エラーになる…。

最初、何でエラーが出るか分からなかったが…
色々なんかした結果『View-based Application』で
作られるビューだと気が付いた…。

で『[actionSheet showInView:self.window];』と
『window』にする事で解決したのだが…。

『delegate:self』の所で警告が出ていたので
『delegate:nil』にして警告を消していたら
『actionSheet』が呼び出されない…。

こんな警告…。
>warning: class 'xxxxApplicationDelegate' does not implement the 'UIActionSheetDelegate' protocol

『delegate:self』にすれば警告は出るが動く…。

どこかで設定し忘れているらしい…。

あ!ヘッダーを設定するのかぁ!?

とヘッダーを
>@interface xxxxAppDelegate : NSObject <UIApplicationDelegate> {
から
>@interface xxxxAppDelegate : NSObject <UIApplicationDelegate, UIActionSheetDelegate> {
に書き換えたら警告が出なくなった…。

最終的にこうなった。
xxxxAppDelegete.h
@interface xxxxAppDelegate : NSObject <UIApplicationDelegate, UIActionSheetDelegate> {
xxxxAppDelegete.m
- (IBAction)pushDoButton:(id)sender {
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"やるの?" delegate:self cancelButtonTitle:@"やめる" destructiveButtonTitle:@"やる" otherButtonTitles:nil];
    [actionSheet showInView:self.view];
    [actionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(buttonIndex!=0) {
        // 『やる』処理
    }
}

柔軟なのは、良いけど…
分かり難いよ…。

初心者なんでRPG宜しく経験値を稼いでいる所…。(汗)

| | コメント (2) | トラックバック (0)

より以前の記事一覧