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 顺序在拖动过程中保持不变。在下面的图片中,我正在拖动国王。注意它是如何正确地位于左图中的九之上,但不正确地位于右图中的二之下(实际上是在整个堆栈之下):

在此处输入图像描述 在此处输入图像描述

我也尝试过更改layer.zPosition属性,但无济于事。如何在拖动过程中将卡片视图置于前面?我很迷惑。

4

1 回答 1

8

确认的。bringSubviewToFront:导致layoutSubview被调用。由于我的版本layoutSubviews在所有视图上设置了 z 顺序,因此这将撤消我在touchesBegan:withEvent上面的代码中设置的 z 顺序。bringSubviewToFront苹果应该在文档中提到这个副作用。

我没有使用UIView子类,而是创建了一个CALayer名为CardLayer. 我在我的KlondikeView子类中处理触摸,如下所示。topZPosition 是一个实例变量,它跟踪所有卡片的最高 zPosition。请注意,修改zPosition通常是动画的——我在下面的代码中将其关闭:

-(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 回答