2014-10-20 8 views
5

Załóżmy ParentViewcontroller jako P, FirstViewController jako V1 i SecondViewController jako V2.viewDidAppear wywołał na viewcontroller, który jest zwalniany w iOS8

Przedstawiam V1 od P, a następnie V2 od V1. Teraz chcę przejść bezpośrednio do P. W tym celu używam

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

Działa to dobrze w iOS7. Ale w iOS8 mam do czynienia z problemem (nie wiem, czy to problem, czy nie) podczas tego. To jest wywoływana metoda viewDidAppear V1, a także jej widok na ekranie przez ułamek sekundy.

Czy to jest funkcja iOS8 lub błąd? Czy jest jakiś alternatywny sposób na zrobienie tego?

ViewControllers przedstawiający kod.

Od P, gdzie P jest popychany viewcontroller,

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

Od V1,

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

Nie wiem, czy to będzie żadnej różnicy, ale dismissModalViewControllerAnimated: była amortyzowana dawno temu, należy używać dismissViewControllerAnimated: Zakończenie :. – rdelmar

+0

Dziękuję @rdelmar. To był problem z wklejeniem kopii. Skopiowano stary kod. Zmieniono moje pytanie :). – iCanCode

+0

to nie wygląda na błąd. Tego można się spodziewać w oparciu o to, co robisz. W jaki sposób prezentujesz kontrolery widoku? Opublikuj kod prezentacyjny – Lefteris

Odpowiedz

0

Możesz użyć embed V1 w NavigationController (NV)? W ten sposób możesz popchnąć swoją V2. Następnie można przejść do wersji V1 lub odrzucić NV do P.

+0

Nie! Nie mogę. Jestem w stanie zrobić P. P. Mój problem polega na tym, że kiedy przechodzę do P bezpośrednio z V2, to V_s wgląda w usterki przez ułamek sekundy. – iCanCode

0

Po spędzeniu dużej ilości czasu na badaniach zakończyło się łatanie problemu.

To co zrobiłem to, że przed zwolnieniem ViewController (V2) zrobiłem zrzut ekranu ParentViewcontroller (P) i dodałem go do okna aplikacji. Następnie usunięto obraz z okna po zwolnieniu kontrolera 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

Fakt, że „viewWill/DidAppear” jest wywoływana, gdy odrzucisz V1 logiczne jest to technicznie V1 jest narażona na modalnej zwolnienia górnego viewController (V2), jeśli tylko na tyle długo, że UIKit następnie pobiera zadanie aby usunąć następny podstawowy viewController (np. V1).

Domyślam się, że wizualna usterka V1 w iOS8 nie jest błędem i ma więcej wspólnego z tym, jak iOS radzi sobie z odrzuceniem modalnego środka modemu w iOS8. Ponieważ nie istnieje żadna dokumentacja dla tej sytuacji, jej faktyczne zachowanie może legalnie zmienić się z iOS na iOS.

Myślę, że jednym ze sposobów robienia tego, co chcesz zrobić, zachowania kompatybilności wstecznej ze starszymi systemami iOS i używania API z udokumentowanym zachowaniem, byłoby użycie kodu takiego jak poniżej (być może jako kategorii na UIViewController). aby ożywić V1, a później po prostu go usunąć (# 2 poniżej). V2 może być prawdopodobnie animowany w V1 przy użyciu standardowego kontrolera iOS 'presentViewController, ale możesz również użyć do niego metody # 1.

Jedna uwaga jest taka, że ​​od kiedy dodajesz V1.view jako widok podzbiór do P zamiast przez system modalny UIViewController, stracisz zautomatyzowane wywołania viewWill/DidAppear w V1. Więc musisz wywołać te ręcznie. W tym przykładzie są wywoływane w metodzie "animacji w górę".

To nie jest kod, którego używam, ale robiłem podobne rzeczy w przeszłości. Więc bądź ostrożny i skomentuj, jeśli błędy zostaną znalezione .... zakłada ARC:

Mam nadzieję, że to pomoże.

//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!! 
    }