Ακύρωση μιας animation UIView;

ψήφοι
221

Είναι δυνατόν να ακυρώσετε μια UIViewκινούμενη εικόνα, ενώ είναι σε εξέλιξη; Ή θα πρέπει να μειωθεί στο επίπεδο CA;

δηλαδή έχω κάνει κάτι τέτοιο (ίσως και τον καθορισμό καταληκτικής δράση animation πάρα πολύ):

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

// set view properties

[UIView commitAnimations];

Αλλά πριν ολοκληρωθεί το animation και παίρνω την κίνηση έληξε περίπτωση, θέλω να το ακυρώσετε (κόβουμε σύντομο). Είναι δυνατόν; Googling γύρω βρίσκει μερικούς ανθρώπους που ρωτούν την ίδια ερώτηση χωρίς απάντηση - και ένα ή δύο άτομα εικασίες ότι δεν μπορεί να γίνει.

Δημοσιεύθηκε 17/02/2009 στις 00:19
πηγή χρήστη
Σε άλλες γλώσσες...                            


17 απαντήσεις

ψήφοι
342

Χρήση:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];
Απαντήθηκε 19/03/2010 στις 07:53
πηγή χρήστη

ψήφοι
111

Ο τρόπος που το κάνετε είναι να δημιουργήσετε ένα νέο animation για το σημείο προορισμού σας. Ορίστε μια πολύ σύντομη διάρκεια και βεβαιωθείτε ότι χρησιμοποιείτε τη +setAnimationBeginsFromCurrentState:μέθοδο για να ξεκινήσει από την τρέχουσα κατάσταση. Όταν οριστεί σε Ναι, η τρέχουσα animation κόβεται απότομα. Φαίνεται κάτι σαν αυτό:

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

// set view properties

[UIView commitAnimations];
Απαντήθηκε 08/05/2009 στις 22:46
πηγή χρήστη

ψήφοι
61

Απλούστερος τρόπος για να σταματήσει όλες τις κινήσεις σε μια συγκεκριμένη άποψη, αμέσως , είναι το εξής:

Σύνδεση του έργου με QuartzCore.framework. Κατά την έναρξη του κώδικά σας:

#import <QuartzCore/QuartzCore.h>

Τώρα, όταν θέλετε να σταματήσει όλες τις κινούμενες εικόνες σε ένα νεκρό θέα στις διαδρομές τους, να πω το εξής:

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

Η μεσαία γραμμή θα λειτουργήσει από μόνη της, αλλά υπάρχει μια καθυστέρηση μέχρι να ολοκληρωθεί η runloop (το «αναδιατυπώσει στιγμή»). Για να αποφύγετε αυτή την καθυστέρηση, τυλίξτε την εντολή με σαφή μπλοκ συναλλαγή, όπως φαίνεται. Οι αυτή η εργασία παρέχεται χωρίς άλλες αλλαγές έχουν πραγματοποιηθεί σε αυτό το επίπεδο στην τρέχουσα runloop.

Απαντήθηκε 04/01/2012 στις 00:03
πηγή χρήστη

ψήφοι
43

Στο iOS 4 και μεγαλύτερη, χρησιμοποιήστε την UIViewAnimationOptionBeginFromCurrentStateεπιλογή στο δεύτερο animation για να κοπεί το πρώτο animation σύντομη.

Για παράδειγμα, ας υποθέσουμε ότι έχετε μια άποψη με ένα δείκτη δραστηριότητας. Θα ήθελα να ξεθωριάζει στον δείκτη δραστηριότητας, ενώ κάποια δυνητικά χρόνο δραστηριότητας κατανάλωση αρχίζει και ξεθωριάζει έξω όταν η δραστηριότητα ολοκληρωθεί. Στον παρακάτω κώδικα, η άποψη με τον δείκτη δραστηριότητας λέγεται 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;
                     }
                 }];
}
Απαντήθηκε 11/08/2011 στις 09:30
πηγή χρήστη

ψήφοι
39

Για να ακυρώσετε μια κινούμενη εικόνα που απλά πρέπει να ρυθμίσετε το ακίνητο που βρίσκεται στο στάδιο κινουμένων σχεδίων, έξω από το animation UIView. Αυτό θα σταματήσει το animation όπου και αν είναι, και η UIView θα μεταβεί στη ρύθμιση που μόλις ορίστηκε.

Απαντήθηκε 19/06/2010 στις 18:09
πηγή χρήστη

ψήφοι
9

Αν εμψύχωση μια πίεση από την αλλαγή της σταθεράς αντί για καμία άποψη ιδιοκτησία των άλλων μεθόδων εργάζονται για iOS 8.

Παράδειγμα animation:

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];
}
Απαντήθηκε 07/11/2014 στις 17:21
πηγή χρήστη

ψήφοι
8

Συγγνώμη για να αναστήσει αυτή την απάντηση, αλλά στο iOS 10 πράγματα κάπως αλλάξει, και τώρα ακύρωση είναι δυνατή και μπορείτε ακόμη και να ακυρώσετε την χάρη!

Μετά iOS 10 μπορείτε να ακυρώσετε κινούμενα σχέδια με UIViewPropertyAnimator !

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

Αν περνάτε αλήθεια ότι ακυρώνει την κίνηση και σταματά ακριβώς εκεί που ακυρώθηκε. Η μέθοδος ολοκλήρωσης δεν θα γίνει. Ωστόσο, αν έχετε περάσει ψευδή είστε υπεύθυνοι για το τελείωμα της κίνησης:

animator.finishAnimation(.start)

Μπορείτε να ολοκληρώσετε τη ζωτικότητά σας και να μείνετε στην τρέχουσα κατάσταση (.current) ή να πάτε στην αρχική κατάσταση (.start) ή στο τέλος κατάσταση (.end)

Με την ευκαιρία, μπορείτε ακόμη και να διακόψετε και να επανεκκινήσετε αργότερα ...

animator.pauseAnimation()
animator.startAnimation()

Σημείωση: Εάν δεν θέλετε μια απότομη ακύρωση μπορείτε να αντιστρέψετε κινούμενα σχέδια σας ή ακόμα και να αλλάξετε κινούμενα σχέδια σας μετά την παύση!

Απαντήθηκε 09/11/2017 στις 17:57
πηγή χρήστη

ψήφοι
7

Αν θέλετε απλώς να κάνετε παύση / διακοπή animation ομαλά

self.yourView.layer.speed = 0;

Πηγή: Πώς να διακόψετε την κίνηση ενός δέντρου στρώματος

Απαντήθηκε 29/06/2015 στις 11:02
πηγή χρήστη

ψήφοι
5
[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];
Απαντήθηκε 06/02/2015 στις 05:30
πηγή χρήστη

ψήφοι
5

Κανένα από τα παραπάνω θα λυθεί για μένα, αλλά αυτό βοήθησε: Η UIViewκινούμενη εικόνα παρουσιάζει το ακίνητο αμέσως, τότε ζωντανεύει. Σταματά την κίνηση, όταν το στρώμα παρουσίασης ταιριάζει με το μοντέλο (ο ορισμός της ιδιότητας).

Θα λυθεί το θέμα μου, η οποία ήταν «Θέλω να εμψυχώσει από όπου θα φαίνεται σαν να φαίνεται» ( «εσείς» σημαίνει τη θέα). Αν θέλετε αυτό, τότε:

  1. Προσθήκη QuartzCore.
  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) {}];

Και αυτό θα πρέπει να είναι ένα αξιοπρεπές λύση για τώρα.

Απαντήθηκε 16/08/2011 στις 18:21
πηγή χρήστη

ψήφοι
1

Εχω το ίδιο πρόβλημα; τα APIs δεν έχουν τίποτα να ακυρώσετε κάποιο συγκεκριμένο animation. ο

+ (void)setAnimationsEnabled:(BOOL)enabled

απενεργοποιεί όλες τις κινούμενες εικόνες, και ως εκ τούτου δεν λειτουργεί για μένα. Υπάρχουν δύο λύσεις:

1) φτιάχνουν κινούμενα σας αντιταχθούν σε δευτερεύουσας προβολής. Στη συνέχεια, όταν θέλετε να ακυρώσετε τις κινήσεις για τη συγκεκριμένη προβολή, αφαιρέστε την προβολή ή απόκρυψη. Πολύ απλό, αλλά θα πρέπει να αναδημιουργήσει τον δευτερεύουσας προβολής χωρίς κινούμενα σχέδια, αν πρέπει να το κρατήσει κατά την άποψη.

2) επαναλάβετε τη anim μόνο μία, και να κάνει έναν επιλογέα εκπρόσωπο να κάνετε επανεκκίνηση του anim, αν χρειαστεί, όπως αυτό:

-(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) είναι ότι υπάρχει πάντα καθυστερούν τη διακοπή της anim και τελειώνει τον τρέχοντα κύκλο animation.

Η ελπίδα αυτό βοηθά.

Απαντήθηκε 08/05/2009 στις 18:03
πηγή χρήστη

ψήφοι
0

Κανένας από τους απάντησε λύσεις λειτούργησε για μένα. Έλυσα θέματα μου με αυτόν τον τρόπο (δεν ξέρω αν είναι σωστό τρόπο;), γιατί είχα προβλήματα όταν καλείτε αυτό το πάρα πολύ γρήγορη (όταν η προηγούμενη animation δεν ήταν ακόμα έτοιμο). Έχω περάσει επιθυμητό animation μου με 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()
                }
        })

    }

}
Απαντήθηκε 20/08/2019 στις 14:52
πηγή χρήστη

ψήφοι
0

Όταν δουλεύω με 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)
}
Απαντήθηκε 07/02/2019 στις 09:03
πηγή χρήστη

ψήφοι
0

Ταχεία έκδοση της λύσης Στεφάνου Ντάρλινγκτον

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

// set view properties
UIView.commitAnimations()
Απαντήθηκε 26/12/2017 στις 15:09
πηγή χρήστη

ψήφοι
0

Για να διακόψετε μια κινούμενη εικόνα χωρίς εκ νέου κράτους στην αρχική ή την τελική:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;
Απαντήθηκε 03/12/2015 στις 21:43
πηγή χρήστη

ψήφοι
0
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];
Απαντήθηκε 28/01/2013 στις 15:54
πηγή χρήστη

ψήφοι
0

Ακόμα και αν ακυρώσετε την κίνηση στους τρόπους παραπάνω animation didStopSelectorεξακολουθεί να λειτουργεί. Έτσι, αν έχετε λογικές καταστάσεις στην εφαρμογή σας οδηγείται από κινούμενα σχέδια θα έχετε προβλήματα. Για το λόγο αυτό, με τους τρόπους που περιγράφονται παραπάνω μπορώ να χρησιμοποιήσω το πλαίσιο μεταβλητή UIViewκινούμενα σχέδια. Αν περάσει η τρέχουσα κατάσταση του προγράμματος σας από το πλαίσιο param στην κινούμενη εικόνα, όταν η κίνηση σταματά σας didStopSelectorλειτουργία μπορεί να αποφασίσει αν πρέπει να κάνει κάτι ή απλά να επιστρέψουν με βάση την τρέχουσα κατάσταση και την αξία κράτους πέρασε ως πλαίσιο.

Απαντήθηκε 05/10/2010 στις 09:52
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more