7

ユーザーが通常の方法でカードをドラッグできるようにする単純な iOS ソリティア ゲームを実装しています。カードはUIViewサブクラスで表されCardViewます。すべてのカード ビューは、 のサブビューである兄弟ですSolitaireView。次のスニペットは、「カードを前面に持ってくる」ことを試みて、ドラッグされているときに他のすべてのビューの上に表示されるようにします。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
   UITouch *touch = [touches anyObject];
   if (touch.view.tag == CARD_TAG) {
      CardView *cardView = (CardView*) touch.view;
      ...
      [self bringSubviewToFront:cardView];
      ...
   }
}

残念ながら、カードの z オーダーはドラッグ中に変更されません。下の画像では、キングをドラッグしています。左の画像では正しく Nine の上にあるのに、右の画像では間違って Two の下 (実際にはスタック全体の下) にあることに注意してください。

ここに画像の説明を入力 ここに画像の説明を入力

layer.zPositionまた、プロパティも変更しようとしましたが、役に立ちませんでした。ドラッグ中にカード ビューを前面に移動するにはどうすればよいですか? 私は当惑しています。

4

1 に答える 1

8

確認済み。呼び出されるbringSubviewToFront:原因。layoutSubview私のバージョンの はlayoutSubviewsすべてのビューで z オーダーを設定するため、touchesBegan:withEvent上記のコードで設定していた z オーダーを元に戻していました。Apple は、ドキュメントでこの副作用について言及する必要がありbringSubviewToFrontます。

サブクラスを使用する代わりに、という名前UIViewのサブクラスを作成しました。以下に示すように、サブクラスでタッチを処理します。topZPosition は、すべてのカードの最高の zPosition を追跡するインスタンス変数です。の変更は通常アニメーション化されることに注意してください。以下のコードではこれをオフにしています。CALayerCardLayerKlondikeViewzPosition

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
   UITouch *touch = [touches anyObject];
   CGPoint touchPoint = [touch locationInView:self];
   CGPoint hitTestPoint = [self.layer convertPoint:touchPoint
                                           toLayer:self.layer.superlayer];
   CALayer *layer = [self.layer hitTest:hitTestPoint];

   if (layer == nil) return;

   if ([layer.name isEqual:@"card"]) {
     CardLayer *cardLayer = (CardLayer*) layer;
     Card *card = cardLayer.card;

     if ([self.solitaire isCardFaceUp:card]) {
        //...                                                                                                            
        [CATransaction begin]; // disable animation of z change                                                                  
        [CATransaction setValue:(id)kCFBooleanTrue
                         forKey:kCATransactionDisableActions];              
        cardLayer.zPosition = topZPosition++; // bring to highest z

        // ... if card fan, bring whole fan to top

        [CATransaction commit];
        //...                                                                                                            
     }
     // ...                                                                                                             
   }

}
于 2012-04-06T03:10:45.117 に答える