Zrušení animace UIView?

hlasů
221

Je možné zrušit UIViewanimaci, zatímco v jejím průběhu? Jinak bych musel klesnout na úroveň CA?

tj jsem udělal něco takového (možná nastavení animační akci konec taky):

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

// set view properties

[UIView commitAnimations];

Ale dříve, než se animace dokončí a mám animace končil události, chci zrušit (rozseká ji v krátkosti). Je to možné? Googling kolem najde pár lidí, kteří žádají stejnou otázku bez odpovědi - a jeden nebo dva lidé spekulují, že to nemůže být provedeno.

Položena 17/02/2009 v 00:19
zdroj uživatelem
V jiných jazycích...                            


17 odpovědí

hlasů
342

Použití:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];
Odpovězeno 19/03/2010 v 07:53
zdroj uživatelem

hlasů
111

Jak jsem to udělat, je vytvořit novou animaci ke svému koncovému bodu. Nastavit velmi krátkou dobu a ujistěte se, že použití +setAnimationBeginsFromCurrentState:metody vycházejí z aktuálního stavu. Když ji nastavíte na YES, aktuální animace je zarazena. Vypadá nějak takto:

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

// set view properties

[UIView commitAnimations];
Odpovězeno 08/05/2009 v 22:46
zdroj uživatelem

hlasů
61

Nejjednodušší způsob, jak zastavit všechny animace v určitém pohledu, okamžitě , je toto:

Odkaz na projekt QuartzCore.framework. Na začátku kódu:

#import <QuartzCore/QuartzCore.h>

Nyní, když chcete zastavit všechny animace na zobrazení mrtvých v jejich stopách, říci toto:

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

Prostřední řada bude fungovat samo od sebe, ale je tu zpoždění dokud runloop úprav (dále jen „překreslení moment“). Aby se zabránilo, že zpoždění, zabalit příkaz v explicitním bloku transakce, jak je uvedeno. To funguje neposkytla žádné další změny byly provedeny v této vrstvě v aktuálním runloop.

Odpovězeno 04/01/2012 v 00:03
zdroj uživatelem

hlasů
43

Na iOS 4 a vyšší, použijte UIViewAnimationOptionBeginFromCurrentStatevolbu ve druhém animace snížit první animace krátký.

Jako příklad předpokládejme, že máte názor s indikátorem aktivity. Chcete-li slábnout v ukazateli aktivity, zatímco některé potenciálně časově náročné aktivity začíná a fade to, když se ukončí svou činnost. V kódu níže, pohled s ukazatelem aktivity na něm, se nazývá 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;
                     }
                 }];
}
Odpovězeno 11/08/2011 v 09:30
zdroj uživatelem

hlasů
39

Chcete-li zrušit animaci stačí jednoduše nastavit vlastnost, která je v současné době animovaný, mimo animace UIView. Že se zastaví animace tam, kde je, a UIView skočí do nastavení jste právě definována.

Odpovězeno 19/06/2010 v 18:09
zdroj uživatelem

hlasů
9

Pokud máte animaci omezení změnou konstanty namísto pohledu majetku žádný z dalších metod práce na iOS 8.

Příklad animace:

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) {

                 }];

Řešení:

Je třeba odstranit animace z vrstev případné názory jsou ovlivněny změnou omezujícími podmínkami a jejich dílčích vrstev.

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}
Odpovězeno 07/11/2014 v 17:21
zdroj uživatelem

hlasů
8

Omlouvám se, že vzkřísit tuto odpověď, ale v iOS 10 věci trochu změnily, a nyní rušení je možné a dokonce můžete zrušit elegantně!

Po iOS 10. můžete zrušit animace s UIViewPropertyAnimator !

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

Pokud předat pravda, že zruší animaci a zastaví se přesně tam, kde ji zruší. nebude volána metoda dokončení. Nicméně, pokud si projít false jste zodpovědní za ukončení animace:

animator.finishAnimation(.start)

Můžete dokončit svou animaci a pobyt v aktuálním stavu (.current), nebo jít do počátečního stavu (.start), nebo do koncového stavu (.end)

Mimochodem, můžete si dokonce pozastavit a restartovat později ...

animator.pauseAnimation()
animator.startAnimation()

Poznámka: Pokud nechcete, aby náhlé zrušení můžete obrátit animace, nebo dokonce změnit animaci po jejím pozastavení!

Odpovězeno 09/11/2017 v 17:57
zdroj uživatelem

hlasů
7

Pokud chcete jen pozastavit / zastavit animaci plynule

self.yourView.layer.speed = 0;

Zdroj: Jak pozastavit animaci stromu vrstev

Odpovězeno 29/06/2015 v 11:02
zdroj uživatelem

hlasů
5
[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];
Odpovězeno 06/02/2015 v 05:30
zdroj uživatelem

hlasů
5

Nic z výše uvedeného je vyřešen pro mě, ale to pomohlo: The UIViewanimace okamžitě nastaví vlastnost, pak ji oživuje. Zastaví animaci, když prezentační vrstva odpovídá modelu (soubor nemovitostí).

Vyřešil jsem svůj problém, který byl „Chci oživit, odkud se vypadat, jako byste se objeví“ ( ‚Vy‘ znamená, zobrazení). Že pokud chcete, pak:

  1. Přidat QuartzCore.
  2. CALayer * pLayer = theView.layer.presentationLayer;

nastavit pozici na prezentační vrstvy

Používám několik možností, včetně UIViewAnimationOptionOverrideInheritedDuration

Ale proto, že dokumentace Apple je nejasný, já nevím, jestli je to opravdu přednost jiné animace při použití, nebo jen resetuje časovače.

[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) {}];

A že by měl být slušný řešení pro tuto chvíli.

Odpovězeno 16/08/2011 v 18:21
zdroj uživatelem

hlasů
1

Mám stejný problém; API nemají nic společného zrušit některé konkrétní animace.

+ (void)setAnimationsEnabled:(BOOL)enabled

zakáže všechny animace, a tak nefunguje pro mě. Tam jsou dvě řešení:

1) vytvořit svůj animovaný objekt se subview. Pak, když chcete zrušit animace k tomuto názoru, odstraňte zobrazení nebo skrýt. Velmi jednoduché, ale je třeba znovu subview bez animací, pokud je třeba ji mít na zřeteli.

2) opakujte anim pouze jedno, a aby se volič delegáta restartovat anim v případě potřeby, jako je tento:

-(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];
}
}

Problém s 2), je to, že tam je vždy zpoždění zastavení anim, jak to skončí aktuální animační cyklus.

Snad to pomůže.

Odpovězeno 08/05/2009 v 18:03
zdroj uživatelem

hlasů
0

Žádný z zodpovězených řešení pracoval pro mě. Vyřešil jsem mé problémy tímto způsobem (já nevím, jestli je to správná cesta?), Protože jsem měl problémy při volání toto příliš rychlý (když předchozí animace ještě nebyl dokončen). Předám svou požadovanou animaci customAnim bloku.

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()
                }
        })

    }

}
Odpovězeno 20/08/2019 v 14:52
zdroj uživatelem

hlasů
0

Když pracuji s UIStackViewanimací, kromě toho removeAllAnimations()musím nastavit některé hodnoty počáteční jedno, protože removeAllAnimations()lze nastavit na nepředvídatelném stavu. Musím stackViewse view1i view2uvnitř, a jeden pohled by měl být viditelný a jeden skrytý:

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)
}
Odpovězeno 07/02/2019 v 09:03
zdroj uživatelem

hlasů
0

Swift verze Stephena Darlington řešení

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

// set view properties
UIView.commitAnimations()
Odpovězeno 26/12/2017 v 15:09
zdroj uživatelem

hlasů
0

Chcete-li pozastavit animaci, aniž by návrat do stavu původní nebo v konečném znění:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;
Odpovězeno 03/12/2015 v 21:43
zdroj uživatelem

hlasů
0
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];
Odpovězeno 28/01/2013 v 15:54
zdroj uživatelem

hlasů
0

I když zrušíte animace ve výše popsaných způsobů animace didStopSelectorstále běží. Takže pokud máte logické stavy v aplikaci poháněn animací budete mít problémy. Z tohoto důvodu se způsoby, jak je popsáno výše mohu použít kontextovou proměnnou UIViewanimací. Pokud předat aktuální stav vašeho programu kontextového param k animaci, když se animace zastaví vaše didStopSelectorfunkce může rozhodnout, zda je třeba něco dělat, nebo prostě vrátit na základě aktuálního stavu a hodnotou státní předán jako kontext.

Odpovězeno 05/10/2010 v 09:52
zdroj uživatelem

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