0

私はこれを何時間も理解しようとしてきましたが、ここでは完全に途方に暮れています。ゲームにカスタムUIImageViewの一部を実装しようとしてUIPinchGestureRecognizerいますが、機能しません。私が調査したすべてのことは、それが機能するはずだと言っていますが、そうではありません。ピンチをビューコントローラまたはカスタムUIViewに追加すると正常に機能しますが、UIImageViewsには追加できません。私はすべての一般的な修正と微調整を試しましたが、成功しませんでした。はいに設定しましたuserInteractionEnabledmultipleTouchEnabledデリゲートとセレクターを適切に設定しています。shouldRecognizeSimultaneouslyWithGestureRecognizerYESを返すように設定しました。

ジェスチャレコグナイザーがUIImageViewに追加され、更新ループの後半でそのプロパティにアクセスできましたが、ピンチしようとしたときにセレクターのNSLogがUIImageViewに対して呼び出されることはありません。ビューのz位置を調整して、ビューが上にあるがサイコロがないことを確認しました。

私のUIImageViewsはNSMutableDictionaryに保存され、ゲームの各更新ループ中にループすることで更新されます。これは、UIPinchGestureRecognizerが呼び出されないことに影響を与える可能性がありますか?...他に何も考えられず、コードを投稿してもおそらく役に立たないでしょう-UIViewまたはViewControllerに使用した場合とまったく同じコードが機能するためです。

ビューコントローラのtouchesBeganイベントとtouchedMovedイベントにタッチ処理コードがあります...しかし、それをオフにしましたが、問題は解決せず、ピンチはとにかく他の要素で機能しました。

UIImageViewでジェスチャセレクターが起動するのを妨げる可能性のあるアイデアはありますか?辞書?ゲームループで絶えず更新されることと何か関係がありますか?どんなアイデアでも歓迎します、これは実装がとても簡単なようです...

編集:UIImageViewのコードとそれを使って何をしているのか...これが役立つかどうかはわかりません。

拡張UIImageViewクラスPaper.m(prpはstruct、カスタム変数を初期化するために使用されるプロパティの1つです。

NSString *tName =  [NSString stringWithUTF8String: prp.imagePath];
UIImage *tImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png",tName]];
self = [self initWithImage: tImage];
self.userInteractionEnabled = YES;
self.multipleTouchEnabled = YES;
self.center = CGPointMake(prp.spawnX, prp.spawnY);
if (prp.zPos != 0)  { self.layer.zPosition = prp.zPos; }
// other initialization excised

次に、NSMutableDictionaryを保持し、そのようにすべてのUIImageViewオブジェクトを初期化するObjManagerというカスタムクラスがあります。ここで、addObjは、各オブジェクトを追加するためにループで呼び出されます。

- (ObjManager*) initWithBlank {
    // create an array for our objects
    self = [super init];
    if (self) {
        objects = [[NSMutableDictionary alloc] init];
        spawnID = 100;  // start of counter for dynamically spawned object IDs
    }
    return self;
}

- (void) addObj:(Paper *)paperPiece wasSpawned:(BOOL)spawned {
    // add each paper piece, assign spawnID if dynamically spawned
    NSNumber *newID;
    if (spawned) { newID = [NSNumber numberWithInt:spawnID]; spawnID++; }
    else         { newID = [NSNumber numberWithInt:paperPiece.objID]; }
    [objects setObject:paperPiece forKey:newID];
}

ビューコントローラは、ObjManagerの初期化を呼び出します(VCでは_worldと呼ばれます)。次に、次のように_worldをループします。

// Populate additional object managers and add all subviews
for (NSNumber *key in _world.objects) {

    _eachPiece = [_world.objects objectForKey:key];

    // Populate collision object manager
    if (_eachPiece.collision) {
        [_world_collisions addObj:_eachPiece wasSpawned:NO];
    }

    // only add pinch gesture if the object flag is set
    if (_eachPiece.pinch) {  
        UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchPaper:)];
        pinchGesture.delegate = self;
        [_eachPiece addGestureRecognizer:pinchGesture];
        NSLog(@"Added pinch recognizer scale: %@", pinchGesture.view.description);
    }

    // Add each object as a subview
    [self.view addSubview:_eachPiece];

}

_eachPieceは、ビューコントローラのオブジェクトであり、.hファイルで宣言されています(_worldと同様)。

@property (nonatomic, strong) ObjManager *world; 
@property (nonatomic, strong) Paper *eachPiece;

次に、_world(ObjManager)内のすべての移動可能なPaperオブジェクト(UIImageViews)を次のようにフレームごとに更新するNSTimerオブジェクトがあります。

// loop through each piece and update
for (NSNumber *key in _world.objects) {

    eachPiece = [_world.objects objectForKey:key];

    // only update moveable pieces
    if ((eachPiece.moveType == Move_Touch) || (eachPiece.moveType == Move_Auto)) {

        CGPoint paperCenter;
        paperCenter = eachPiece.center;

        // a bunch of code to update paperCenter x & y for the object's new position based on velocity and user input

        // determine image direction and transformation matrix
        [_world updateDirection:eachPiece];
        CGAffineTransform transformPiece = [_world imageTransform:eachPiece];
        if (transformEnabled) {
            eachPiece.transform = transformPiece;
        }

        // finally move it
        [eachPiece setCenter:paperCenter];

    }

}

そしてピンチセレクター:

- (void)pinchPaper:(UIPinchGestureRecognizer *)recognizer {
    NSLog(@"Pinch scale: %f", recognizer.scale);
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    recognizer.scale = 1;
}

私の知る限り、ピンチは機能するはずです。同じピンチジェスチャコードをビューコントローラに追加するように設定すると、ビュー全体で機能します。また、境界線(ビューの周りに描かれた長方形)として機能するカスタムUIViewクラスがあり、ピンチジェスチャコードをそこに移動すると、境界線のみをピンチできます。

4

2 に答える 2

2

よし、ジェスチャ認識エンジンは、位置がアニメーション化されているビューでは起動しないようです。したがって、それを機能させるには、View Controllerに認識機能を配置してから、ヒットテストを実行し、ピンチ/ズームしたい場合は、タッチしたビューにピンチ/ズームを適用する必要がありました。その情報はこちら:

http://iphonedevsdk.com/forum/iphone-sdk-tutorials/100982-caanimation-tutorial.html

私の特定のケースでは、View Controller レベルの変数/配列で、ピンチしたいアニメーション ビューを追跡しました。次に、セレクターでこのコードを使用しました(基本的に上記のリンクから、すべてそれらの功績によるものです):

- (void)pinchPaper:(UIPinchGestureRecognizer *)recognizer {

    CALayer *pinchLayer;
    id layerDelegate;
    CGPoint touchPoint = [recognizer locationInView:self.view];

    pinchLayer = [self.view.layer.presentationLayer hitTest: touchPoint];
    layerDelegate = [pinchLayer delegate];

    //_pinchView is the UIView I want to pinch
    if (layerDelegate == _pinchView) {
        _pinchView.transform = CGAffineTransformScale(_pinchView.transform, recognizer.scale, recognizer.scale);
        recognizer.scale = 1;
    }
}

注意が必要なのは、既存の UIView アニメーションの一部として他のスケール変換 (私の方向の変更など) が行われている場合、各更新ループ中に現在の変換を使用して、それを考慮する必要があることです。

于 2012-12-11T06:24:54.373 に答える
1

ジェスチャ認識エンジンが imageView で機能するには、userInteraction を有効にする必要があります。

だから、そうあるべきです、

yourImageView.userInteractionEnabled = YES;

または、ストーリーボードを使用している場合は、ストーリーボードのインスペクター ウィンドウでもそのオプションを確認できます。

それが役に立てば幸い..:)

于 2012-12-03T09:37:26.023 に答える