2013-10-16 9 views
11

Sto vedendo che tutte le animazioni ios nella mia app smettono di funzionare. Sta accadendo molto frequentemente in iOS7.Le animazioni iOS smettono di funzionare nella mia app in iOS7

Ehi ragazzi avevo un'app che supporta iOS 5, 6 e 7. Di recente vedo che tutte le animazioni iOS smettono di funzionare nell'app in iOS7 ??

+0

non so il motivo dietro di esso, ma ho avuto esattamente lo stesso problema ed è stato risolto quando ho rimosso un tableView: willDisplayCell: forRowAtIndexPath: il metodo che ha usato per chiamare un sacco di performSelectorInBackground per visualizzare le immagini. Questo può aiutare o dare qualche suggerimento per risolvere il problema. – Mohammad

+0

in realtà ho trovato out.It succede quando si fa roba UIKit in background thread.Here è il link che spiega tutto. http://stackoverflow.com/questions/18281097/uiviewcontroller-animations-stop-working – user1010819

risposta

24

In IOS 7 quando alcune azioni del metodo principale vengono eseguite sul thread in background, le animazioni vengono disabilitate.

quindi per questo è necessario riattivare le animazioni come (Una soluzione)

[UIView setAnimationsEnabled:YES]; 

Può essere questo può aiutare.

+3

Lo sto contrassegnando come corretto anche se questo è un problema.Nessuna azione del metodo principale dovrebbe essere eseguita nel thread in background. – user1010819

+2

Concordo sul fatto che si tratta solo di una soluzione. –

1

Estendendo la soluzione di Vinay, che è quello che faccio:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      //make calculations 
      dispatch_async(dispatch_get_main_queue(), 
          ^{ 
           [UIView setAnimationsEnabled:YES]; 
          });   
}); 

sembra risolvere il problema.

+0

questa è la risposta peggiore che mi aspettavo: D – l0gg3r

+0

non è perfetto ma funziona –

+0

a cosa serve la comunicazione esterna async? Non puoi semplicemente rimuoverlo? – AntiMoron

16

Recentemente mi sono imbattuto in questo problema con alcune viste che sto valutando per i calcoli delle dimensioni sul thread in background. Sbalzando setAnimationsEnabled:, ho trovato che il tempo solo in cui stavo disattivando le animazioni dal thread in background era -[UIImageView setImage:].

Perché questo punto di vista non è mai stato reso e immagine cambia non sono stati richiesti per il mio calcolo, sono stato in grado di racchiudere questa prova in una chiamata thread principale:

if ([NSThread isMainThread]) { 
    self.answerImageView.image = [UIImage imageNamed:imgName]; 
} 

Vale la pena notare non mi ha colpito questo problema nella visualizzazione di un'istanza iniziale, perché ho già caricare le mie opinioni template nel thread principale per evitare un problema di carico XI ter.

Altri problemi possono essere più complessi, ma si dovrebbe essere in grado di trovare soluzioni alternative simili. Ecco la categoria che uso per rilevare la disabilitazione di sfondo delle animazioni.

#import <UIKit/UIKit.h> 
#import <JRSwizzle/JRSwizzle.h> 

#ifdef DEBUG 

@implementation UIView (BadBackgroundBehavior) 

+ (void)load 
{ 
    NSError *error = nil; 
    if (![self jr_swizzleClassMethod:@selector(setAnimationsEnabled:) withClassMethod:@selector(SE_setAnimationsEnabled:) error:&error]) { 
     NSLog(@"Error! %@", error); 
    } 
} 

+ (void)SE_setAnimationsEnabled:(BOOL)enabled 
{ 
    NSAssert([NSThread isMainThread], @"This method is not thread safe. Look at the backtrace and decide if you really need to be doing this here."); 
    [self SE_setAnimationsEnabled:enabled]; 
} 

@end 

#endif 

Aggiornamento

Si scopre che in realtà UIWebView rende le chiamate non sicuri per l'setAnimationsEnabled: durante la visualizzazione di un elemento di supporto (rdar: // 20.314.684). Ciò rende il metodo di cui sopra molto doloroso per avere attiva tutto il tempo se la vostra applicazione permette di contenuti Web arbitrario. Invece ho iniziato ad usare il metodo seguito in quanto mi permette di girare il punto di interruzione e si spegne e continuare dopo il fallimento:

#import <UIKit/UIKit.h> 
#import <objc/runtime.h> 

#ifdef DEBUG 

void SEViewAlertForUnsafeBackgroundCalls() { 
    NSLog(@"----------------------------------------------------------------------------------"); 
    NSLog(@"Background call to setAnimationsEnabled: detected. This method is not thread safe."); 
    NSLog(@"Set a breakpoint at SEUIViewDidSetAnimationsOffMainThread to inspect this call."); 
    NSLog(@"----------------------------------------------------------------------------------"); 
} 

@implementation UIView (BadBackgroundBehavior) 

+ (void)load 
{ 
    method_exchangeImplementations(class_getInstanceMethod(object_getClass(self), @selector(setAnimationsEnabled:)), 
            class_getInstanceMethod(object_getClass(self), @selector(SE_setAnimationsEnabled:))); 
} 

+ (void)SE_setAnimationsEnabled:(BOOL)enabled 
{ 
    if (![NSThread isMainThread]) { 
     SEViewAlertForUnsafeBackgroundCalls(); 
    } 
    [self SE_setAnimationsEnabled:enabled]; 
} 

@end 

#endif 

Con questo codice, è possibile interrompere la vostra applicazione con l'aggiunta di un punto di interruzione simbolica sulla SEViewAlertForUnsafeBackgroundCalls o semplicemente attaccare un punto di interruzione nel corpo della funzione.

Gist

+0

Questa risposta è sorprendente. Ogni volta che questa asserzione viene lanciata, vedrai nel tuo codice sorgente dove hai incasinato e hai cercato di fare qualcosa non sul thread principale. –

+0

Stavo sperimentando questo comportamento a causa di una webview che continuava a fare chiamate non sicure a setAnimationsEnabled: e corro in condizioni di gara con altre animazioni di viste. C'è un modo per risolvere questa assurdità di questa webview? L'adozione di WKWebView non è un'opzione perché la webview è incapsulata in una classe di terze parti. Sbatterebbe permanentemente setAnimationsEnabled: forzare l'esecuzione nel main è troppo pericoloso? – ArkReversed

Problemi correlati