我正在实现一个简单的 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:
causes layoutSubview
被调用。自从我的版本layoutSubviews
在所有视图上设置 z 顺序,这会撤消我在中设置的 z 顺序touchesBegan:withEvent
上面的代码。苹果应该在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];
//...
}
// ...
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)