2012-04-04 13 views
7

पर दृश्य लाएं मैं एक साधारण आईओएस सॉलिटेयर गेम को कार्यान्वित कर रहा हूं जो उपयोगकर्ता को सामान्य तरीके से कार्ड खींचने की अनुमति देता है। कार्ड UIView उपclass CardView के साथ प्रदर्शित होते हैं। सभी कार्ड व्यू भाई बहन हैं जो SolitaireView के सबव्यूव हैं। निम्नलिखित स्निपेट "सामने करने के लिए एक कार्ड लाने" की कोशिश करता है, ताकि यह अन्य सभी दृश्यों के ऊपर है के रूप में यह घसीटा जा रहा है:UIView bringSubviewToFront: * नहीं * सामने

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

दुर्भाग्य से, कार्ड के ज़ेड-ऑर्डर खींचें दौरान अपरिवर्तित रहता है। नीचे दी गई छवियों में, मैं राजा को खींच रहा हूं। गौर करें कि यह शीर्ष नौ बाईं छवि में पर सही ढंग से है, लेकिन गलत तरीके से (पूरे ढेर के नीचे वास्तव में) सही छवि में दो के अधीन है:

enter image description hereenter image description here

मैं भी रूप में layer.zPosition संपत्ति को बदलने की कोशिश की कोई फायदा नहीं हुआ। ड्रैग के दौरान मैं सामने के कार्ड दृश्य को कैसे ला सकता हूं? मैं रहस्यमय हूँ।

+0

मुझे पता चला कि 'bringSubviewToFront:' चलाता है दृश्य की 'needsLayout' ध्वज स्थापित किया जाना। मेरा 'लेआउट सबव्यूव्स' विधि 'लाने के लिए भी कॉल कर रहा था' लाउसव्यूव्यूफ्रंट: 'इस प्रकार सभी दृश्य जेड-ऑर्डर को अपने प्रारंभिक अवस्था में वापस कर दिया गया! – wcochran

+0

फिर इसके लिए समाधान क्या है? मुझे भी इसी तरह की आवश्यकताएं हैं, जहां कार्ड की सूची से, यदि मैं किसी भी मध्य ऑर्डर कार्ड का चयन करता हूं, तो इसे सामने आना चाहिए, फिर सामने आना चाहिए। लेकिन मेरी एनीमेशन लाने के कारण काम नहीं कर रहा है SubviewToFront: विधि – Mrunal

+0

यदि आप UIView उपclasses का उपयोग करने के साथ चिपके रहते हैं तो आपको कार्ड को खींचा जा रहा है ताकि लेआउटस्यूब्यूव इसे शीर्ष पर रख सकें। जैसा कि मैंने नीचे उल्लिखित कैलियर का उपयोग करने के लिए वास्तव में स्विच किया था। – wcochran

उत्तर

8

पुष्टि की। bringSubviewToFront: का कारण बनने के लिए layoutSubview का कारण बनता है। चूंकि layoutSubviews का मेरा संस्करण सभी विचारों पर जेड-ऑर्डर सेट करता है, इसलिए यह ऊपर दिए गए touchesBegan:withEvent कोड में जेड-ऑर्डर को पूर्ववत कर रहा था। ऐप्पल को bringSubviewToFront दस्तावेज में इस दुष्प्रभाव का उल्लेख करना चाहिए।

बजाय एक UIView उपवर्ग का उपयोग करने का

, मैं एक CALayer उपवर्ग CardLayer नाम बनाया। मैं नीचे सूचीबद्ध के रूप में मेरे KlondikeView सबक्लास में स्पर्श को संभालता हूं। topZPosition एक उदाहरण var है जो सभी कार्डों की उच्चतम 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]; 
     //...                            
    } 
    // ...                            
    } 

} 
+4

पर मुझे लगता है कि कार्ड खेलने के लिए 'UIView' का उपयोग करना खराब डिजाइन विकल्प हो सकता है - मुझे नहीं लगता कि वे वास्तव में इरादे से थे इसके लिए। मुझे लगता है कि मैं वापस कदम उठाऊंगा और इसके बजाय 'कैलियर' का उपयोग करूंगा। – wcochran