2014-10-20 7 views
5

Supponiamo ParentViewcontroller come P, FirstViewController come V1 e SecondViewController come V2.viewDidAppear ha chiamato su un viewcontroller che è stato ignorato in iOS8

Sto presentando V1 da P poi V2 da V1. Ora voglio andare direttamente a P. Per questo sto usando

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:NO completion:nil]; 

Questo funziona bene in iOS7. Ma in iOS 8 sto affrontando un problema (non so se si tratta di un problema o meno) quando si fa questo. Questo è il metodo viewDidAppear di V1 che viene chiamato e anche i suoi glitch di visualizzazione sullo schermo per una frazione di secondo.

Questa funzione o bug di iOS8 ?. C'è un modo alternativo per farlo?

ViewControllers che presenta il codice.

Da P, dove P è un viewcontroller spinto,

ViewController1 *v1 = [[ViewController1 alloc] init];  
[self presentViewController:v1 animated:NO completion:nil]; 

Da V1,

ViewController2 *v2 = [[ViewController2 alloc] init]; 
[self presentViewController:v2 animated:NO completion:nil]; 
+0

Non so se farà alcuna differenza, ma dismissModalViewControllerAnimated: è stato ammortizzato molto tempo fa, si dovrebbe utilizzare dismissViewControllerAnimated: completamento :. – rdelmar

+0

Grazie @rdelmar. Era un problema di copia incolla. Copiato un vecchio codice. Modificato la mia domanda :). – iCanCode

+0

questo non mi sembra un bug. Questo dovrebbe essere previsto in base a ciò che stai facendo. Come stai presentando i controller di visualizzazione? Invia il codice di presentazione – Lefteris

risposta

0

Potete usare il vostro incorporare V1 a navigationController (NV)? In questo modo, puoi spingere il tuo V2. Quindi è possibile accedere a V1 o ignorare NV a P.

+0

No! Non posso Sono in grado di andare a P. Il mio problema è quando goto P direttamente da V2, i glitch di vista V1 per una frazione di secondo. – iCanCode

0

Dopo aver trascorso un sacco di tempo nella ricerca è terminato patching del problema.

Quello che ho fatto è, prima di chiudere il ViewController (V2), ho catturato una schermata di ParentViewcontroller (P) e l'ho aggiunto alla finestra dell'applicazione. Quindi rimosso l'immagine dalla finestra dopo il licenziamento di ViewController (V2).

CGRect deviceRect = [[UIScreen mainScreen] bounds]; 

UIGraphicsBeginImageContextWithOptions(deviceRect.size, NO, [UIScreen mainScreen].scale); 
CGContextRef contextRef = UIGraphicsGetCurrentContext(); 
CGContextTranslateCTM(contextRef, -deviceRect.origin.x, -deviceRect.origin.y); 
[[self.presentingViewController.presentingViewController.view layer] renderInContext:contextRef]; 
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

UIImageView *windowImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, deviceRect.size.width, deviceRect.size.height)]; 
[windowImageView setImage:capturedImage]; 
[[[UIApplication sharedApplication] keyWindow] addSubview:windowImageView]; 

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:NO completion:^ 
{ 
     [windowImageView removeFromSuperview]; 
}]; 
0

Il fatto che 'viewWill/DidAppear' è invocato quando si elimina V1 è logico tecnicamente V1 è esposto il licenziamento modale della parte superiore viewController (V2), anche se solo per un periodo sufficiente che UIKit poi si fa il compito rimuovere il successivo viewController sottostante (ad es. V1).

La mia ipotesi sarebbe il difetto visivo V1 in iOS8 non è un bug e altro ha a che fare con il modo in cui iOS gestisce il licenziamento di una modale-dentro-a-modale in iOS8. Poiché non esiste documentazione per quella situazione, il suo comportamento effettivo può legittimamente cambiare da iOS a iOS.

Penso che un modo per fare ciò che si vuole fare, mantenere la retrocompatibilità con i vecchi iOS e utilizzare le API con un comportamento documentato, utilizzi il codice come di seguito (forse come categoria su UIViewController). per animare V1, quindi in seguito semplicemente rimuoverlo (n. 2 in basso). Probabilmente V2 potrebbe essere animato all'interno di V1 usando lo standard iOS 'presentViewController', ma potresti anche usare il metodo # 1 per questo.

Una nota è che poiché si aggiunge V1.view come subview a P invece che attraverso il sistema modale UIViewController, si perderanno le chiamate viewWill/DidAppear automatiche in V1. Quindi dovresti invocare quelli manualmente. In questo esempio vengono richiamati nel metodo della categoria 'animate up'.

Questo non è il codice che sto effettivamente usando, ma ho fatto cose simili in passato. Quindi sii un po 'attento e si prega di commentare se vengono trovati errori .... assume ARC:

Spero che questo aiuti.

//1. animate V1 up (executed from P) 
    ViewController * V1 = [[ViewController1 alloc] init]; 
    //place V1 view below bottom of P 
    V1.view.frame = CGRectMake(0, UI_phone_height, UI_phone_width, UI_phone_height); 
    [self.view addSubview: V1.view]; //'self' is P 
    [V1 customAnimateUpCategory]; 

    // >> method #1 in a UIViewController category 
    - (void) customAnimateUpCategory { 

      //...optional 
      [self viewWillAppear]; 

      [UIView animateWithDuration:0.4 
        animations:^ { 
         //animate V1.view up 
         self.view.frame = CGRectMake(0, 0, UI_phone_width, UI_phone_height); 
        } 
        completion:^ (BOOL finished) { 
         if (finished) { 
          //...optional 
          [self viewDidAppear]; 
         } 
        } 
      ]; 
    } 


    //2. make V1/V2 disappear without animation (executed from V2) 
    //'V1' is weakly held in V2 as an IVAR 
    [self.V1 removeViewCategory] 

    // >> method #2 in a UIViewController category 
    - (void) removeViewCategory { 
      [self.view removeFromSuperview];//should remove and release V1/V2 glitch free!! 
    } 
Problemi correlati