31

पर आधारित UIView एनीमेशन, मैं फ़ोटो एप में आईफोन के निर्माण में छवियों के बीच ब्राउज़ करने की तरह स्क्रीन पर और बाहर एक सबव्यूव स्थानांतरित करने में सक्षम होना चाहता हूं, इसलिए अगर सबव्यू 1/2 से अधिक स्क्रीन है जब मैं अपनी उंगली से जाने देता हूं तो उसे स्क्रीन से एनिमेट करना होगा, लेकिन इसे स्वाइप का भी समर्थन करना चाहिए ताकि अगर स्वाइप/पैन वेग पर्याप्त हो, तो स्क्रीन को एनिमेट करना होगा, भले ही स्क्रीन से 1/2 से कम हो।UIVanGestureRecognizer वेग

मेरा विचार UIPanGestureRecognizer का उपयोग करना था और फिर वेग पर परीक्षण करना था। यह काम करता है, लेकिन मैं दृश्य के वर्तमान स्थान और पैन की वेग के आधार पर UIView को स्थानांतरित करने के लिए एक सही एनीमेशन अवधि कैसे सेट करूं ताकि यह चिकनी लगती हो? यदि मैं एक निश्चित मान निर्धारित करता हूं, तो एनीमेशन या तो मेरी अंगुलियों की तुलना में धीमा या तेज़ गति से शुरू होता है।

उत्तर

47

डॉक्स कहना

पैन इशारा है, जो प्रति सेकंड अंक में व्यक्त किया है के वेग। वेग क्षैतिज और ऊर्ध्वाधर घटकों में टूट गया है।

तो मैं, कहेंगे आप अपना दृश्य ले जाना चाहते दिया xPoints (पीटी में मापा जाता है) यह जाना ऑफ स्क्रीन जाने के लिए, यदि आप ऐसा जैसे कि आंदोलन के लिए अवधि की गणना कर सकते हैं:

CGFloat xPoints = 320.0; 
CGFloat velocityX = [panRecognizer velocityInView:aView].x; 
NSTimeInterval duration = xPoints/velocityX; 
CGPoint offScreenCenter = moveView.center; 
offScreenCenter.x += xPoints; 
[UIView animateWithDuration:duration animations:^{ 
    moveView.center = offScreenCenter; 
}]; 

हालांकि आप + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion का उपयोग करना चाहेंगे और अलग-अलग UIViewAnimationOptions को आजमाएं।

20

UIPanGestureRecognizer में वेग पर भरोसा करने पर एक अवलोकन: मुझे आपके अनुभव के बारे में पता नहीं है, लेकिन मुझे सिम्युलेटर पर सिस्टम उत्पन्न वेग बहुत उपयोगी नहीं पाया गया है। (यह डिवाइस पर ठीक है, लेकिन सिम्युलेटर पर समस्याग्रस्त है।)

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

मैं मैन्युअल रूप से वेग की गणना करना समाप्त कर दिया। (यह मूर्खतापूर्ण लगता है कि यह जरूरी है, लेकिन अगर मैं वास्तव में पैन की अंतिम गति प्राप्त करना चाहता था तो मुझे इसके चारों ओर कोई रास्ता नहीं दिख रहा था।) नीचे की रेखा, जब राज्य UIGestureRecognizerStateChanged है, तो मैं वर्तमान और पिछले translationInView का ट्रैक रखता हूं CGPoint के साथ-साथ समय, और फिर उन मानों का उपयोग करते हुए जब मैं UIGestureRecognizerStateEnded में वास्तविक अंतिम वेग की गणना करने के लिए था। यह बहुत अच्छी तरह से काम करता है।

वेग की गणना के लिए मेरा कोड यहां है। मैं एनीमेशन की गति को समझने के लिए वेग का उपयोग नहीं कर रहा हूं, बल्कि मैं यह निर्धारित करने के लिए उपयोग कर रहा हूं कि उपयोगकर्ता या तो स्क्रीन पर आधे रास्ते से अधिक स्थानांतरित करने के लिए दृश्य के लिए पर्याप्त रूप से पर्याप्त या फिसल गया है या नहीं विचारों के बीच एनीमेशन को ट्रिगर करना, लेकिन अंतिम वेग की गणना करने की अवधारणा इस प्रश्न पर लागू होती है। कोड यह रहा:

- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture 
{ 
    static CGPoint lastTranslate; // the last value 
    static CGPoint prevTranslate; // the value before that one 
    static NSTimeInterval lastTime; 
    static NSTimeInterval prevTime; 

    CGPoint translate = [gesture translationInView:self.view]; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     lastTime = [NSDate timeIntervalSinceReferenceDate]; 
     lastTranslate = translate; 
     prevTime = lastTime; 
     prevTranslate = lastTranslate; 
    } 
    else if (gesture.state == UIGestureRecognizerStateChanged) 
    { 
     prevTime = lastTime; 
     prevTranslate = lastTranslate; 
     lastTime = [NSDate timeIntervalSinceReferenceDate]; 
     lastTranslate = translate; 

     [self moveSubviewsBy:translate]; 
    } 
    else if (gesture.state == UIGestureRecognizerStateEnded) 
    { 
     CGPoint swipeVelocity = CGPointZero; 

     NSTimeInterval seconds = [NSDate timeIntervalSinceReferenceDate] - prevTime; 
     if (seconds) 
     { 
      swipeVelocity = CGPointMake((translate.x - prevTranslate.x)/seconds, (translate.y - prevTranslate.y)/seconds); 
     } 

     float inertiaSeconds = 1.0; // let's calculate where that flick would take us this far in the future 
     CGPoint final = CGPointMake(translate.x + swipeVelocity.x * inertiaSeconds, translate.y + swipeVelocity.y * inertiaSeconds); 

     [self animateSubviewsUsing:final]; 
    } 
} 
+0

यह आईओएस 6 में काम नहीं करता है क्योंकि अंतिम अनुवाद और अंतिम ट्रान्सलेशन 'यूआईजीएस्टर रिकॉग्नाइज़रस्टेटएंडेड' में समान है, इसलिए अंतिम वेग हमेशा 0. – an0

+1

धन्यवाद, मैं देखता हूं। यह सिम्युलेटर का मुद्दा है। मैंने ऐप्पल को एक बग रिपोर्ट निकाल दी। – an0

+0

उम्मीद है कि मैंने इस भ्रम से बचने के लिए स्रोत (कुछ परिवर्तनीय नाम बदलना) संशोधित किया है। यह कोड ठीक काम करता था जैसा कि था, लेकिन उम्मीद है कि नए चर नामों ने इसे थोड़ा कम भ्रमित कर दिया है। ऐप्पल को बग की रिपोर्ट करने के लिए धन्यवाद। – Rob

1

ज्यादातर मामलों में UIViewAnimationOptionBeginFromCurrentState विकल्प UIView एनिमेटर के लिए एक दोषरहित जारी रखा एनीमेशन बनाने के लिए पर्याप्त है की स्थापना।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^