2012-04-04 18 views
7

Kullanıcının kartları her zamanki gibi sürüklemesini sağlayan basit bir iOS solitaire oyunu uyguluyorum. Kartlar UIView alt sınıf CardView ile temsil edilir. Tüm kart görünümleri, SolitaireView'un alt görünümleri olan kardeşlerdir. Aşağıdaki Ön bilgi sürüklenen gibi tüm diğer görüntüleme civarında olacak şekilde "ön bir kart getir" çalışır: UIView bringSubviewToFront: does * not * önden görünümü getir

-(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]; 
     ... 
    } 
} 

Maalesef kartın z sırasını sürükle sırasında değişmeden kalır. Aşağıdaki resimlerde, Kral'ı sürüklüyorum. Ben aynı zamanda layer.zPosition özelliğini değiştirmek çalıştı

enter image description hereenter image description here

: Bu üst sol görüntüde Nine doğru olmakla sağ görüntüde (aslında tüm yığının altında) İki altında yanlış oluşuna dikkat edin hayır boşuna iyi. Sürükleme sırasında kart görünümünü öne nasıl getirebilirim? Ben gizemliyim.

+0

ben' bringSubviewToFront keşfetti: Aşağıda kodda bunu kapat - zPosition genellikle animasyonlu değiştirerek unutmayın. 'LayoutSubviews' yöntemim de' bringSubviewToFront: 'işlevini çağırıyordu ve böylece tüm görünümleri z-siparişlerini ilk durumuna geri döndürdü! – wcochran

+0

O zaman bunun çözümü nedir? Aynı tür şartlara da sahibim, kartların listesinden, eğer orta sipariş kartlarından birini seçersem, gelmeli, sonra önden gelmeliyim. ama benim animomuz bringSubviewToFront nedeniyle çalışmaz: method – Mrunal

+0

UIView alt sınıflarını kullanarak yapışırsanız, sürüklenen kartı işaretlemeniz gerekir, böylece layoutSubviews en üste yerleştirebilir. Ben aslında aşağıda belirtildiği gibi CALayers kullanmaya geçtim. – wcochran

cevap

8

Onaylandı. bringSubviewToFront:, çağrılacak layoutSubview neden olur. layoutSubviews sürümüm, tüm görünümlerde z-siparişlerini belirlediğinden, bu, yukarıdaki touchesBegan:withEvent kodunda ayarlayan z sırasını siliyordu. Apple, bu yan etkiyi bringSubviewToFront belgelerinde belirtmelidir.

UIView alt sınıfının yerine, CardLayer adlı CALayer alt sınıfını oluşturdum. Aşağıda belirtildiği gibi KlondikeView alt sınıfımda dokunma. topZPosition, tüm kartların en yüksek zPpozisyonunu izleyen bir örnek var. `Ayarlanması görünümün 'needsLayout' bayrağını tetikler:

-(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]; 
     //...                            
    } 
    // ...                            
    } 

} 
+4

'UIView' oyun kartları için kötü bir tasarım tercih edilmiş olabilir düşünüyorum - onlar gerçekten amaçlanmış olduğunu sanmıyorum bunun için. Sanırım geri adım atıp 'CALayer' yerine kullanacağım. – wcochran