ios - एक UIView एनीमेशन रद्द करें?


क्या यह प्रगति पर है जब एक UIView एनीमेशन को रद्द करना संभव है? या मुझे सीए स्तर पर छोड़ना होगा?

यानी मैंने ऐसा कुछ किया है (शायद एक एनीमेशन एक्शन एक्शन भी सेट करना):

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

लेकिन एनीमेशन पूर्ण होने से पहले और मुझे ऐनिमेशन समाप्त होने की घटना मिलती है, मैं इसे रद्द करना चाहता हूँ (इसे कम करें)। क्या यह संभव है? चारों ओर Googling कोई जवाब नहीं के साथ एक ही सवाल पूछने वाले कुछ लोगों को पाता है - और एक या दो लोग अनुमान लगाते हैं कि यह नहीं किया जा सकता है।


Answers



जिस तरह से मैं करता हूँ, वह अपने अंत बिंदु पर एक नया एनीमेशन बनाने के लिए है। एक बहुत ही कम अवधि निर्धारित करें और सुनिश्चित करें कि आप +setAnimationBeginsFromCurrentState: मौजूदा स्थिति से शुरू करने के लिए विधि का उपयोग करें। जब आप इसे YES पर सेट करते हैं, तो वर्तमान एनीमेशन कम हो जाता है। ऐसा कुछ दिखता है:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];



उपयोग:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];



एक विशेष दृश्य पर सभी एनिमेशन को रोकने का सबसे आसान तरीका, तुरंत यह है:

परियोजना को क्वार्ट्ज़कोर.फ्रेमवर्क पर लिंक करें आपके कोड की शुरुआत में:

#import <QuartzCore/QuartzCore.h>

अब, जब आप सभी एनिमेशन को उनके ट्रैक में मरने पर रोकना चाहते हैं, तो यह कहें:

[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];

मध्य रेखा अपने आप से सब कुछ काम करेगी, लेकिन रनलोप खत्म होने तक ("रेड्रा पल") में देरी हो सकती है। उस देरी को रोकने के लिए, दिखाए गए अनुसार एक स्पष्ट लेन-देन ब्लॉक में कमांड को लपेटो। यह काम इस स्तर पर मौजूदा रन-लूप में कोई अन्य परिवर्तन नहीं किया गया है।




IOS 4 और अधिक पर, पहली एनीमेशन शॉर्ट कट करने के लिए दूसरी एनीमेशन पर UIViewAnimationOptionBeginFromCurrentState विकल्प का उपयोग करें

एक उदाहरण के रूप में, मान लें कि आपके पास गतिविधि संकेतक के साथ एक दृश्य है। आप गतिविधि सूचक में फीका करना चाहते हैं, जबकि कुछ संभावित समय लेने वाली गतिविधि शुरू होती है, और गतिविधि समाप्त होने पर इसे फीका कर देती है। नीचे दिए गए कोड में, उस पर गतिविधि सूचक के साथ दृश्य को गतिविधि दृश्य कहा जाता activityView

- (void)showActivityIndicator {
    activityView.alpha = 0.0;
    activityView.hidden = NO;
    [UIView animateWithDuration:0.5
                 animations:^(void) {
                     activityView.alpha = 1.0;
                 }];

- (void)hideActivityIndicator {
    [UIView animateWithDuration:0.5
                 delay:0 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^(void) {
                     activityView.alpha = 0.0;
                 }
                 completion:^(BOOL completed) {
                     if (completed) {
                         activityView.hidden = YES;
                     }
                 }];
}



एनीमेशन रद्द करने के लिए आपको बस उस संपत्ति को सेट करने की आवश्यकता है जिसे वर्तमान में एनिमेटेड किया जा रहा है, UIView एनीमेशन के बाहर। यह कहीं भी एनीमेशन को रोक देगा, और UIView आपके द्वारा परिभाषित की जाने वाली सेटिंग में कूद जाएगा।




यदि आप एक दृश्य संपत्ति के बजाय लगातार बदलकर एक बाधा को एनिमेट कर रहे हैं IOS 8 पर काम करने वाले अन्य तरीकों में से कोई भी नहीं।

उदाहरण एनीमेशन:

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

उपाय:

बाधा परिवर्तन से प्रभावित होने वाले किसी भी विचार की परतों और उनके उपस्तरों को आप एनिमेशन से हटाने की जरूरत है

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}






उपरोक्त में से कोई भी यह मेरे लिए हल नहीं किया, लेकिन यह मदद करता है: UIView एनीमेशन तुरंत संपत्ति सेट करता है, फिर इसे एनिमेट करता है। यह एनीमेशन बंद हो जाता है जब प्रस्तुति स्तर मॉडल (सेट प्रॉपर्टी) से मेल खाता हो।

मैंने अपनी समस्या का समाधान किया, जो "मैं चाहता हूं कि आप जिस तरह से दिखते हों, से चेतन करना चाहते हैं" ('आप' को देखने का मतलब है)। यदि आप चाहते हैं कि, तब:

  1. क्वार्ट्जकोर जोड़ें
  2. CALayer * pLayer = theView.layer.presentationLayer;

प्रस्तुति परत में स्थिति निर्धारित करें

मैं UIViewAnimationOptionOverrideInheritedDuration सहित कुछ विकल्पों का उपयोग करता हूं

लेकिन क्योंकि ऐप्पल के दस्तावेज़ीकरण अस्पष्ट है, मुझे नहीं पता है कि क्या यह वाकई दूसरे एनीमेशन को ओवरराइड करता है, या सिर्फ टाइमर रीसेट करता है

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

और यह अब के लिए एक सभ्य समाधान होना चाहिए।




[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];



मेरी भी यही समस्या है; एपीआई के पास कुछ विशिष्ट एनीमेशन को रद्द करने के लिए कुछ भी नहीं है।

+ (void)setAnimationsEnabled:(BOOL)enabled

सभी एनिमेशन को अक्षम करता है, और इस तरह मेरे लिए काम नहीं करता है दो समाधान हैं:

1) अपने एनिमेटेड ऑब्जेक्ट को एक सबव्यू बनाएं उसके बाद, जब आप उस दृश्य के एनिमेशन को रद्द करना चाहते हैं, तो दृश्य हटाएं या इसे छुपें। बहुत सरल है, लेकिन आपको एनीमेशन के बिना सबव्यू को फिर से बनाने की ज़रूरत है अगर आपको उसे देखने में रखना चाहिए।

2) एनिम को सिर्फ एक ही दोहराएं, और यदि आवश्यक हो, तो एनिमेशन को पुन: प्रारंभ करने के लिए एक प्रतिनिधि चयनकर्ता बनाएं:

-(void) startAnimation {
NSLog(@"startAnim alpha:%f", self.alpha);
[self setAlpha:1.0];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(pulseAnimationDidStop:finished:context:)];
[self setAlpha:0.1];
[UIView commitAnimations];
}

- (void)pulseAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
if(hasFocus) {
    [self startAnimation];
} else {
    self.alpha = 1.0;
}
}

-(void) setHasFocus:(BOOL)_hasFocus {
hasFocus = _hasFocus;
if(hasFocus) {
    [self startAnimation];
}
}

2 के साथ समस्या) यह है कि हमेशा एनीम को रोकने में देरी है क्योंकि यह वर्तमान एनीमेशन चक्र को खत्म करता है

उम्मीद है की यह मदद करेगा।




इस उत्तर को पुन: उठाने के लिए क्षमा करें, लेकिन आईओएस में 10 चीजें थोड़े बदल गईं हैं, और अब रद्द करना संभव है और आप भी ईर्ष्या से रद्द कर सकते हैं!

IOS 10 के बाद आप UIViewPropertyAnimator के साथ एनिमेशन को रद्द कर सकते हैं!

UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
    view.backgroundColor = .blue
})
animator.stopAnimation(true)

यदि आप सही पास करते हैं तो एनीमेशन को रद्द कर दिया जाता है और यह सही कहां बंद कर देता है, जहां आपने इसे रद्द कर दिया था। पूरा होने का तरीका नहीं कहा जाएगा। हालांकि, अगर आप झूठे पास जाते हैं तो एनीमेशन खत्म करने के लिए आप जिम्मेदार हैं:

animator.finishAnimation(.start)

आप अपने एनीमेशन को समाप्त कर सकते हैं और वर्तमान स्थिति (। वर्तमान) में रह सकते हैं या प्रारंभिक राज्य (। स्टार्टिंग) या अंत राज्य (.end) पर जा सकते हैं।

वैसे, आप बाद में भी रोक सकते हैं और पुनः आरंभ कर सकते हैं ...

animator.pauseAnimation()
animator.startAnimation()

नोट: यदि आप अचानक रद्द नहीं करना चाहते हैं, तो आप अपने एनीमेशन को रिवर्स कर सकते हैं या इसे रोक देने के बाद भी अपनी एनीमेशन बदल सकते हैं!




यहां तक ​​कि अगर आप एनीमेशन के ऊपर दिए गए तरीकों में एनीमेशन को रद्द करते हैं, didStopSelector भी didStopSelector अभी भी चलाता है। इसलिए यदि आपके पास एनीमेशन द्वारा संचालित आपके एप्लिकेशन में लॉजिक स्टेट हैं तो आपको समस्याएं आ जाएंगी ऊपर वर्णित तरीके से इस कारण से मैं UIView एनिमेशन के संदर्भ चर का उपयोग करता हूं। यदि आप एनीमेशन के संदर्भ परम द्वारा अपने प्रोग्राम की वर्तमान स्थिति को पारित करते हैं, तो जब एनीमेशन आपके didStopSelector समारोह को रोक देता है, तो वह तय कर सकता है कि उसे कुछ करना चाहिए या बस वर्तमान स्थिति और संदर्भ के रूप में पारित राज्य मान के आधार पर वापस करना चाहिए।




CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];



राज्य को मूल या अंतिम रूप में वापस लाने के बिना एनीमेशन को रोकने के लिए:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;