ios - UIView bringSubviewToFront : does *not* bring view to front

标签 ios uiview uitouch

我正在实现一个简单的 iOS 单人纸牌游戏,允许用户以通常的方式拖动纸牌。卡片由 UIView 子类 CardView 表示。所有卡片 View 都是兄弟 View ,它们是 SolitaireView 的 subview 。以下代码片段尝试“将卡片置于最前面”,以便它在被拖动时位于所有其他 View 之上:

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

enter image description here enter image description here

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

最佳答案

确认。 bringSubviewToFront: 导致调用 layoutSubview。由于我的 layoutSubviews 版本在所有 View 上设置了 z 顺序,这取消了我在上面的 touchesBegan:withEvent 代码中设置的 z 顺序。 Apple 应该在 bringSubviewToFront 文档中提到这个副作用。

我没有使用 UIView 子类,而是创建了一个名为 CardLayerCALayer 子类。我在我的 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];
        //...                                                                                                            
     }
     // ...                                                                                                             
   }

}

关于ios - UIView bringSubviewToFront : does *not* bring view to front,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10019130/

相关文章:

iOS取消某些地区的触摸事件

ios - UIGestureRecognizer 与 UITouch 代理性能对比

iOS 8 和 segues 抛出意外异常

IOS:使用自动布局根据标题文本调整 UIButton 高度?

屏幕解锁或应用切换时的 iOS View / Controller 生命周期回调

ios - 如何在旋转时处理 UIView 圆角(使用 CAShapeLayer)

ios - 将 UIImageView 置于 UIScrollView 中居中

ios - 如何像在 Apple 的日历应用程序中那样在导航栏 (iOS 7) 中显示/隐藏搜索栏?

ios - UIView(子类)试图呈现 UIImagePickerController

swift - 从多次点击获取坐标并将其返回到数组中以供另一个函数使用