2009-05-26 10 views
14

मैं iPhone पर नज़र रखने छूता है के बारे में एक त्वरित सवाल है और मैं नहीं इस पर एक निष्कर्ष पर किसी भी सुझाव आने के लिए है, तो सक्षम होने के लिए लग रहे हैं की पहचान करना/विचारों बहुत सराहना कर रहे हैं:iPhone: ट्रैकिंग/व्यक्तिगत छूता

मैं आईफोन पर छूने और पहचानने में सक्षम होना चाहते हैं, यानी। मूल रूप से प्रत्येक स्पर्श में एक प्रारंभिक स्थिति और वर्तमान/स्थानांतरित स्थिति होती है। टच एक std :: वेक्टर में संग्रहीत होते हैं और वे समाप्त होने के बाद कंटेनर से हटा दिए जाएंगे। एक बार वे स्थानांतरित होने के बाद उनकी स्थिति अपडेट की जाएगी, लेकिन मैं अभी भी ट्रैक करना चाहता हूं कि वे कहां से शुरू हुए (इशारा पहचान)।

मुझे [घटना ऑल टच] से स्पर्श मिल रहा है, बात यह है कि एनएसएससेट निरस्त नहीं है और मुझे लगता है कि पहले से ही std :: वेक्टर में संग्रहीत स्पर्शों की पहचान करने में सक्षम नहीं है और इसमें स्पर्श एनएसएसएटी (इसलिए मुझे पता है कि कौन से लोग समाप्त हो गए हैं और हटा दिए जाएंगे, या स्थानांतरित किए जाएंगे, आदि)

यहां मेरा कोड है, जो टच स्क्रीन पर केवल एक ही उंगली के साथ पूरी तरह से काम करता है, लेकिन एक से अधिक के साथ , मुझे अप्रत्याशित परिणाम मिलते हैं ...

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    [self handleTouches:[event allTouches]]; 
} 

- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    [self handleTouches:[event allTouches]]; 
} 

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    [self handleTouches:[event allTouches]]; 
} 

- (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    [self handleTouches:[event allTouches]]; 
} 

- (void) handleTouches:(NSSet*)allTouches 
{ 
    for(int i = 0; i < (int)[allTouches count]; ++i) 
    { 
     UITouch* touch = [[allTouches allObjects] objectAtIndex:i]; 
     NSTimeInterval timestamp = [touch timestamp]; 

     CGPoint currentLocation = [touch locationInView:self]; 
     CGPoint previousLocation = [touch previousLocationInView:self]; 

     if([touch phase] == UITouchPhaseBegan) 
     { 
      Finger finger; 
      finger.start.x = currentLocation.x; 
      finger.start.y = currentLocation.y; 
      finger.end = finger.start; 
      finger.hasMoved = false; 
      finger.hasEnded = false; 

      touchScreen->AddFinger(finger); 
     } 
     else if([touch phase] == UITouchPhaseEnded || [touch phase] == UITouchPhaseCancelled) 
     { 
      Finger& finger = touchScreen->GetFingerHandle(i); 

      finger.hasEnded = true; 
     } 
     else if([touch phase] == UITouchPhaseMoved) 
     { 
      Finger& finger = touchScreen->GetFingerHandle(i); 

      finger.end.x = currentLocation.x; 
      finger.end.y = currentLocation.y; 
      finger.hasMoved = true; 
     } 
    } 

    touchScreen->RemoveEnded(); 
} 

धन्यवाद!

उत्तर

7

अपनी समस्या को ठीक करने के लिए अपने "हैंडल टच" विधि को स्क्रैप करें। आपके हैंडल टच विधि में पहली चीज, इसे टचफेस पर स्विच कर देती है, लेकिन यह आपको पहले ही दी गई है। यदि आप स्पर्श में स्पर्श प्राप्त करते हैं, तो आप जानते हैं कि स्पर्श UITouchPhaseBegan में है। चार स्पर्श विधियों से एक विधि में छूने के द्वारा, आप चार प्रतिनिधि तरीकों के उद्देश्य को हरा रहे हैं।

उन तरीकों में से, ऐप्पल आपको वर्तमान स्पर्श के एक अलग चरण से निपटने का अवसर प्रदान करता है।

दूसरी बात यह है कि आपको वर्तमान स्पर्श के लिए ईवेंट को खोजने की आवश्यकता नहीं है, यह आपको पैरामीटर के रूप में दिया जाता है: स्पर्श।

एक कार्यक्रम में छूने के सेट शामिल हैं। दृढ़ता के लिए, आपको वर्तमान स्पर्श दिए जाते हैं भले ही यह घटना के भीतर भी पाया जा सके।

तो, स्पर्शों में, आप एक स्पर्श को ट्रैक करना शुरू करते हैं।

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{ 


     NSString *startPoint = NSStringFromCGPoint([[touches anyObject] locationInView:self]); 

     NSDictionary * touchData = [NSDictionary dictionaryWithObjectsandKeys: startPoint, @"location", touches, @"touch"] 

     [startingLocations addObject:touchData]; 

     } 

मैं अपना स्पर्श डेटा रखने के लिए शब्दकोशों की एक श्रृंखला का उपयोग कर रहा हूं।

अपने कोड को अलग करने और उचित स्पर्श विधि में स्थानांतरित करने का प्रयास करें। दिशा के लिए, ऐप्पल में दो नमूना परियोजनाएं हैं जो स्पर्श पर ध्यान केंद्रित करती हैं और आपको दिखाती हैं कि उन तरीकों को कैसे सेट अप करें।

याद रखें, इन तरीकों प्रत्येक चरण के दौरान प्रत्येक स्पर्श के लिए स्वचालित रूप से कहा जाता हो जाएगा, तो आप पता लगाने के लिए कि क्या हुआ घटना के माध्यम से चक्र की जरूरत नहीं है।

सूचक छूता के प्रत्येक सेट के लिए निरंतर, बस डाटा परिवर्तन बनी हुई है।

इसके अलावा, मैं घटना से निपटने पर iPhone OS प्रोग्रामिंग गाइड अनुभाग जो कि मैं क्या कई चित्र समय के साथ घटनाओं के लिए अंतिम रूप से संबंध समझा साथ ऊपर कहा की अधिक से अधिक गहराई में चला जाता है पढ़ता था।

एक अंश:

iPhone OS में, एक UITouch वस्तु एक स्पर्श का प्रतिनिधित्व करता है, और एक UIEvent वस्तु एक घटना का प्रतिनिधित्व करता है। एक घटना वस्तु वर्तमान मल्टी टच अनुक्रम और के लिए सभी स्पर्श वस्तुओं प्रदान कर सकते हैं स्पर्श एक दृश्य या खिड़की के लिए विशिष्ट वस्तुओं (चित्र 3-2) शामिल हैं। एक स्पर्श वस्तु एक दृश्य के दौरान एक दिया उंगली के लिए लगातार है, और UIKit यह mutates के रूप में यह यह भर उंगली ट्रैक करता है। स्पर्श गुण कि बदलाव स्पर्श के चरण, एक दृश्य में इसके स्थान, अपने पिछले स्थान है, और उसके टाइमस्टैम्प हैं। इवेंट-हैंडलिंग कोड इवेंट में का जवाब देने का तरीका निर्धारित करने के लिए इन विशेषताओं का मूल्यांकन करता है।

+1

मैं आपसे सहमत हूं। मैंने अपने कोड को उचित तरीकों से विभाजित किया। हालांकि, मेरी समस्या यह है कि मुझे ओब्जे-सी और सी ++ के बीच एक लिंक बनाने की आवश्यकता है और घटनाओं के ट्रिगर होने के बाद मेरे गेम आर्किटेक्चर को इनपुट के लिए मतदान की आवश्यकता होती है। यही कारण है कि मैं एसटीएल वेक्टर में छू रहा हूं। वैसे भी, यूआईटीच ऑब्जेक्ट के बारे में आपकी जानकारी समय के साथ लगातार चल रही है। अब, मैं ऑब्जेक्ट में पते का उपयोग विशिष्ट रूप से स्पर्श की पहचान करने के लिए कुंजी के रूप में कर रहा हूं। एक जादू की तरह काम करता है। धन्यवाद। – FlorianZ

+0

"यदि आप स्पर्श में स्पर्श प्राप्त करते हैं, तो आप जानते हैं कि स्पर्श UITouchPhaseBegan में है" - वास्तव में? यह मेरे लिए गलत लगता है - ऐप्पल के दस्तावेज़ों से, वे विपरीत कहते हैं: मल्टी टच के साथ, छूने से एक स्पर्श बीगन किसी भी चरण में हो सकता है। – Adam

+0

@Adam आप गलत पढ़ रहे हैं। हालांकि घटना के भीतर निहित स्पर्श दूसरे चरण में हो सकते हैं। "स्पर्श" पैरामीटर के भीतर सभी स्पर्श निर्दिष्ट चरण में होने की गारंटी देते हैं। इवेंट हैंडलिंग गाइड से: "यदि किसी कारण से आप वर्तमान मल्टीटाउच अनुक्रम में छूने में रूचि रखते हैं जो अंतिम चरण के बाद से नहीं बदला गया है या जो कि पास-इन सेट के अलावा किसी अन्य चरण में हैं, तो आप उनसे अनुरोध कर सकते हैं पास-इन UIEvent ऑब्जेक्ट से। " –

0

आप सभी स्पर्शों के पिछले स्थान को संग्रहीत करके अपने नए स्पर्शों को सही ढंग से एकत्र करने में सक्षम होना चाहिए और फिर नए स्पर्शों का पता लगाए जाने पर इन पिछले स्थानों की तुलना करना चाहिए।

अपने -handleTouches विधि में, आप पाश के लिए अपने में कुछ इस तरह डाल सकता है:

// ..existing code.. 
CGPoint previousLocation = [touch previousLocationInView:self]; 

// Loop through previous touches 
for (int j = 0; j < [previousTouchLocationArray count]; j++) { 
    if (previousLocation == [previousTouchLocationArray objectAtIndex:j]) { 
    // Current touch matches - retrieve from finger handle j and update position 
    } 
} 

// If touch was not found, create a new Finger and associated entry 
जाहिर

आप अपने कोड में इस एकीकृत करने के लिए कुछ काम करने की आवश्यकता होगी, लेकिन मैं बहुत यकीन है कि आप जब वे स्क्रीन के चारों ओर घूमते हैं तो स्पर्शों को सही ढंग से पहचानने के लिए इस विचार का उपयोग कर सकते हैं। इसके अलावा मुझे एहसास हुआ कि CGPoint अच्छी तरह से एनएसएआरएआरई में फिट नहीं होगा - आपको इन्हें NSValue ऑब्जेक्ट्स में लपेटने की आवश्यकता होगी (या एक अलग प्रकार के सरणी का उपयोग करें)।

+0

अच्छा विचार के अनुभाग में और अधिक जानकारी प्राप्त कर सकते हैं। कुछ कारणों से यह मेरे लिए काम नहीं करता है, हालांकि। ऐसा लगता है जैसे पद कभी-कभी बंद होते हैं। यह कम प्रदर्शन के कारण हो सकता है, जब मैं ओपनजीएल संदर्भ में प्रतिपादन कर रहा हूं (मैं एक गेम पर काम कर रहा हूं)। हो सकता है कि स्पर्श घटनाएं तब गिरा दी जाएंगी और पिछले स्थान अब संग्रहीत स्थानों से मेल नहीं खाते हैं? फिर भी आपका धन्यवाद! – FlorianZ

+2

इससे मेरे लिए भी समस्या आई। खासकर जब आप स्क्रीन पर बहुत सारी उंगलियों को ले जाते हैं। कभी-कभी आपको ऐसा स्थान मिलता है जो किसी भी पिछले स्थान से मेल नहीं खाता है। – Nosredna

8

ऐसा लगता है कि कई स्पर्शों को ट्रैक करने के लिए "उचित" तरीका UITouch घटना के सूचक मूल्य से है।

आप "एक परिसर मल्टी टच अनुक्रम हैंडलिंग" इस Apple Developer Documentation

+1

यदि आप केवल पिछले स्थानों को ट्रैक करते हैं और संबंधित स्पर्शों को ढूंढने के लिए इसका उपयोग करते हैं, तो आप सफल नहीं होंगे। अक्सर स्पर्श किया जाता है एक स्थान उस स्थान पर गुजरता है जो आपके सभी कैश किए गए मानों से भिन्न होता है। दस्तावेज़ों को खोजने के लिए "जटिल कॉम्प्लेक्स मल्टी-टच अनुक्रम को संभालने" के लिए Google; लिंक चारों ओर चलता है। एरिका सदून ने इसके बारे में लिखा: http://blogs.oreilly.com/iphone/2008/10/recovering-multiple-touches.html और कुछ कोड भी प्रदान किया: http://github.com/erica/iphone-3.0 -कूकबुक-/ब्लॉब/मास्टर/सी08-जेस्चर/14-आकार बदलें 20 और एंड्रॉइड 20Rotate/main.m मुझे लगता है कि ऐप्पल चाहता है कि यह एनएसएससेट की बजाय एनएसएआरएआरए पास करने के लिए टच एपीआई को दोबारा शुरू कर सके। –