14

iPhone でのタッチの追跡に関して簡単な質問がありますが、これについて結論を出すことができないようです。そのため、提案やアイデアは大歓迎です。

iPhoneのタッチを追跡して識別できるようにしたいです。基本的に、すべてのタッチには開始位置と現在/移動した位置があります。タッチは std::vector に保存され、終了するとコンテナーから削除されます。彼らの位置は移動すると更新されますが、最初に開始した場所 (ジェスチャー認識) を追跡したいと考えています。

[event allTouches] からタッチを取得しています。つまり、NSSet はソートされておらず、std::vector に既に格納されているタッチを識別できず、NSSet 内のタッチを参照できないようです (したがって、どれが終了し、削除されるか、または移動されたかなどがわかります)

もちろん、タッチスクリーン上で1本の指だけで完全に機能しますが、複数の指で予測できない結果が得られます...

    - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    [self handleTouches:[event allTouches]];
}

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

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

- (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
    [self handleTouches:[event allTouches]];
}

- (void) handleTouches:(NSSet*)allTouches
{   
    for(int i = 0; i < (int)[allTouches count]; ++i)
    {
        UITouch* touch = [[allTouches allObjects] objectAtIndex:i];
        NSTimeInterval timestamp = [touch timestamp];

        CGPoint currentLocation = [touch locationInView:self];
        CGPoint previousLocation = [touch previousLocationInView:self];

        if([touch phase] == UITouchPhaseBegan)
        {
            Finger finger;
            finger.start.x = currentLocation.x;
            finger.start.y = currentLocation.y;
            finger.end = finger.start;
            finger.hasMoved = false;
            finger.hasEnded = false;

            touchScreen->AddFinger(finger);
        }
        else if([touch phase] == UITouchPhaseEnded || [touch phase] == UITouchPhaseCancelled)
        {
            Finger& finger = touchScreen->GetFingerHandle(i);

            finger.hasEnded = true;
        }
        else if([touch phase] == UITouchPhaseMoved)
        {
            Finger& finger = touchScreen->GetFingerHandle(i);

            finger.end.x = currentLocation.x;
            finger.end.y = currentLocation.y;
            finger.hasMoved = true;
        }
    }

    touchScreen->RemoveEnded();
}

ありがとう!

4

3 に答える 3

8

複数のタッチを追跡する「適切な」方法は、UITouch イベントのポインター値によるものと思われます。

詳細については、このApple Developer Documentationの「複雑なマルチタッチ シーケンスの処理」セクションを参照してください。

于 2010-03-28T07:18:08.340 に答える
7

問題を解決するには、「handleTouches」メソッドを廃棄してください。handleTouches メソッドで最初に行うことは、touchPhase で切り替えることですが、それは既に与えられています。touchesBegan でタッチを受信した場合、タッチが UITouchPhaseBegan にあることがわかります。4 つのタッチ メソッドから 1 つのメソッドにタッチを集中させると、4 つのデリゲート メソッドを持つ目的が無効になります。

これらの方法のそれぞれで、Apple は現在のタッチのさまざまな段階に対処する機会を提供します。

2 番目のことは、現在のタッチのイベントを検索する必要がないことです。これはパラメーターとして与えられます: touches。

イベントは一連のタッチで構成されます。イベント内でも見つけることができますが、便宜上、現在のタッチが表示されます。

touchesBegan では、タッチの追跡を開始します。

    - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{


        NSString *startPoint = NSStringFromCGPoint([[touches anyObject] locationInView:self]);  

        NSDictionary * touchData = [NSDictionary dictionaryWithObjectsandKeys: startPoint, @"location", touches, @"touch"]

        [startingLocations addObject:touchData];

        }

辞書の配列を使用して、タッチ データを保持しています。

コードを分離して、適切な touch メソッドに移動してみてください。方向性については、Apple はタッチに焦点を当てたいくつかのサンプル プロジェクトを用意しており、それらの方法を設定する方法を示しています。

これらのメソッドは、各フェーズでタッチごとに自動的に呼び出されることに注意してください。何が起こったかを調べるためにイベントを循環する必要はありません。

タッチの各セットへのポインターは一定のままで、データが変更されるだけです。

また、イベント処理に関する iPhone OS プログラミング ガイドのセクションを読むと、時間の経過に伴うタッチとイベントの関係を説明するいくつかの図とともに、上で述べたことをより深く掘り下げることができます。

抜粋:

iPhone OS では、UITouch オブジェクトはタッチを表し、UIEvent オブジェクトはイベントを表します。イベント オブジェクトには、現在のマルチタッチ シーケンスのすべてのタッチ オブジェクトが含まれ、ビューまたはウィンドウに固有のタッチ オブジェクトを提供できます (図 3-2 を参照)。タッチ オブジェクトは、シーケンス中の特定の指に対して永続的であり、UIKit は指を追跡するときにそれを変更します。変更されるタッチ属性は、タッチのフェーズ、ビュー内の位置、以前の位置、およびタイムスタンプです。イベント処理コードは、これらの属性を評価して、イベントへの応答方法を決定します。

于 2009-05-27T04:22:36.057 に答える
0

すべてのタッチの以前の場所を保存し、新しいタッチが検出されたときにこれらの以前の場所を比較することで、タッチを適切に照合できるはずです。

あなたの-handleTouchesメソッドでは、次のようなものをforループに入れることができます。

// ..existing code..
CGPoint previousLocation = [touch previousLocationInView:self];

// Loop through previous touches
for (int j = 0; j < [previousTouchLocationArray count]; j++) {
  if (previousLocation == [previousTouchLocationArray objectAtIndex:j]) {
    // Current touch matches - retrieve from finger handle j and update position
  }
}

// If touch was not found, create a new Finger and associated entry 

明らかに、これをコードに統合するためにいくつかの作業を行う必要がありますが、このアイデアを使用して、タッチが画面上を移動するときにタッチを正しく識別することができると確信しています。また、CGPointがNSArrayにうまく適合しないことに気づきました。これらをNSValueオブジェクトでラップする(または別のタイプの配列を使用する)必要があります。

于 2009-05-26T23:40:12.807 に答える