我采取一个简单的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
财产所有权以及无济于事。 我怎样才能把拖在卡片视图到前面? 我很迷惑。
证实。 bringSubviewToFront:
原因layoutSubview
被调用。 由于我的版本layoutSubviews
设置上的所有意见的z的订单,这被撤销的z顺序,我在设定touchesBegan:withEvent
上面的代码。 苹果应该提到在这种副作用bringSubviewToFront
文档。
而不是使用的UIView
子类,我创建了一个CALayer
指定的子类CardLayer
。 我操作触摸我KlondikeView
子类,如下所示。 topZPosition是一个实例VAR跟踪的所有卡的最高z位置。 需要注意的是修改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];
//...
}
// ...
}
}