سؤال

هل من الممكن إلغاء UIView الرسوم المتحركة بينما هو قيد التقدم؟ أو هل يجب علي إسقاط مستوى كاليفورنيا؟

أي لقد فعلت شيئا مثل هذا (ربما وضع إجراء الرسوم المتحركة نهاية أيضا):

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

// set view properties

[UIView commitAnimations];

ولكن قبل اكتمال الرسوم المتحركة والحصول على الحدث المنتهي في الرسوم المتحركة، أريد إلغاؤه (قصها قصيرة). هل هذا ممكن؟ googling حولها تجد بعض الأشخاص الذين يطرحون نفس السؤال دون أي إجابات - وواحد شخص أو شخصين يتفاقون أنه لا يمكن القيام به.

هل كانت مفيدة؟

المحلول

الطريقة التي أقوم بها هي إنشاء رسوم متحركة جديدة لنقطة النهاية الخاصة بك. تعيين مدة قصيرة جدا وتأكد من استخدام +setAnimationBeginsFromCurrentState: طريقة للبدء من الحالة الحالية. عند ضبطه على نعم، يتم قطع الرسوم المتحركة الحالية قصيرة. يبدو شيئا مثل هذا:

[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];

أبسط طريقة للتوقف الكل الرسوم المتحركة على طريقة عرض معينة، فورا, ، هذا هو:

ربط المشروع إلى Quartzcore.framework. في بداية الرمز الخاص بك:

#import <QuartzCore/QuartzCore.h>

الآن، عندما تريد إيقاف جميع الرسوم المتحركة على ميتا في مساراتهم، قل هذا:

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

سيعمل الخط الأوسط على حد ذاته، ولكن هناك تأخير حتى تنتهي الركض ("لحظة إعادة رسم"). لمنع هذا التأخير، لفت الأمر في كتلة معاملة صريحة كما هو موضح. لم تقدم هذه الأعمال لا توجد تغييرات أخرى في هذه الطبقة في RunLoop الحالي.

على 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 10 أشياء تغير كيندا، والآن إلغاء ممكن ويمكنك حتى الإلغاء بأمان!

بعد iOS 10 يمكنك إلغاء الرسوم المتحركة uiviewpropertyanimator.!

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

إذا قمت بتمرير صحيح، فإنه يلغي الرسوم المتحركة ويتوقف عن الحق في المكان الذي ألغيته. لن يتم استدعاء طريقة الإنجاز. ومع ذلك، إذا قمت بتمرير False، فأنت مسؤول عن الانتهاء من الرسوم المتحركة:

animator.finishAnimation(.start)

يمكنك الانتهاء من الرسوم المتحركة الخاصة بك والبقاء في الحالة الحالية (.Current) أو الذهاب إلى الحالة الأولية (.START) أو إلى حالة النهاية (.END)

بالمناسبة، يمكنك حتى التوقف وإعادة التشغيل لاحقا ...

animator.pauseAnimation()
animator.startAnimation()

ملاحظة: إذا كنت لا تريد إلغاء مفاجئ، فيمكنك عكس الرسوم المتحركة الخاصة بك أو حتى تغيير الرسوم المتحركة الخاصة بك بعد إيقافها مؤقتا!

إذا كنت تقوم بتحريك قيود عن طريق تغيير الثابت بدلا من خاصية عرض أي من الأساليب الأخرى تعمل على 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];
}

إذا كنت تريد فقط إيقاف / إيقاف الرسوم المتحركة بسلاسة

self.yourView.layer.speed = 0;

مصدر: كيفية إيقاف الرسوم المتحركة لشجرة الطبقة

لا شيء مما ذكر أعلاه حلها بالنسبة لي، ولكن هذا ساعد: UIView تحدد الرسوم المتحركة الخاصية الخاصية على الفور، ثم ينشطها. إنه يتوقف عن الرسوم المتحركة عند تطابق طبقة العرض التقديمي من الطراز (خاصية Set).

لقد قمت بحل مشكلتي، والتي كانت "أريد التحريك من حيث تبدو وكأنها تظهر" ("أنت" معنى الرأي). إذا كنت تريد ذلك، ثم:

  1. أضف كوارتزكور.
  2. CALayer * pLayer = theView.layer.presentationLayer;

اضبط الموضع على طبقة العرض التقديمي

يمكنني استخدام بعض الخيارات بما في ذلك UIViewAnimationOptionOverrideInheritedDuration

ولكن نظرا لأن وثائق Apple غامضة، لا أعرف ما إذا كان الأمر يتجاوز الرسوم المتحركة الأخرى عند استخدامها، أو مجرد إعادة تعيين مؤقتات.

[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) هل هناك دائما تأخير إيقاف الرسوم المتحركة لأنها تنتهي من دورة الرسوم المتحركة الحالية.

أتمنى أن يساعدك هذا.

حتى لو قمت بإلغاء الرسوم المتحركة بطرق الرسوم المتحركة أعلاه didStopSelector لا يزال يعمل. لذلك إذا كان لديك حالات منطق في تطبيقك مدفوعة بالرسوم المتحركة، فستكون لديك مشاكل. لهذا السبب مع الطرق الموضحة أعلاه، استخدم متغير السياق UIView الرسوم المتحركة. إذا قمت بتمرير الحالة الحالية لبرنامجك من خلال معركة السياق بالرسوم المتحركة، عندما تتوقف الرسوم المتحركة didStopSelector قد تقرر الدالة ما إذا كان يجب القيام بشيء ما أو العودة فقط بناء على الحالة الحالية وقيمة الدولة التي تم تمريرها كسياق.

نسخة سريعة من حل ستيفن دارلينجتون

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()
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;

عندما أعمل مع UIStackView الرسوم المتحركة، الى جانب ذلك removeAllAnimations() أحتاج إلى تعيين بعض القيم إلى واحد الأولي بسبب removeAllAnimations() يمكن ضبطها على حالة لا يمكن التنبؤ بها. لدي stackView مع view1 و view2 في الداخل، وينبغي أن يكون نظرة واحدة مرئية وواحدة مخفية:

public func configureStackView(hideView1: Bool, hideView2: Bool) {
    let oldHideView1 = view1.isHidden
    let oldHideView2 = view2.isHidden
    view1.layer.removeAllAnimations()
    view2.layer.removeAllAnimations()
    view.layer.removeAllAnimations()
    stackView.layer.removeAllAnimations()
    // after stopping animation the values are unpredictable, so set values to old
    view1.isHidden = oldHideView1 //    <- Solution is here
    view2.isHidden = oldHideView2 //    <- Solution is here

    UIView.animate(withDuration: 0.3,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                    view1.isHidden = hideView1
                    view2.isHidden = hideView2
                    stackView.layoutIfNeeded()
    },
                   completion: nil)
}

لم تنجح أي من الحلول الإجابة بالنسبة لي. قمت بحل مشكلاتي بهذه الطريقة (لا أعرف إذا كانت هناك طريقة صحيحة؟)، لأنني كنت قد تواجه مشاكل عند الاتصال بهذا سريع للغاية (عندما لم تنته بعد الرسوم المتحركة السابقة). اجتياز الرسوم المتحركة المطلوبة مع customanim. منع.

extension UIView
{

    func niceCustomTranstion(
        duration: CGFloat = 0.3,
        options: UIView.AnimationOptions = .transitionCrossDissolve,
        customAnim: @escaping () -> Void
        )
    {
        UIView.transition(
            with: self,
            duration: TimeInterval(duration),
            options: options,
            animations: {
                customAnim()
        },
            completion: { (finished) in
                if !finished
                {
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    self.layer.removeAllAnimations()
                    customAnim()
                }
        })

    }

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top