簡體   English   中英

viewDidAppear調用了一個在iOS8中被解雇的viewcontroller

[英]viewDidAppear called on a viewcontroller which is being dismissed in iOS8

讓我們假設ParentViewcontroller為P,FirstViewController為V1,SecondViewController為V2。

我將從P中呈現V1,然后從V1呈現V2。 現在我想直接去P.對此我正在使用

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

這在iOS7中工作正常。 但是在iOS8中我做這個時遇到了一個問題(不知道是不是問題)。 這就是正在調用V1的viewDidAppear方法,並且它的視圖在屏幕上出現故障只有幾分之一秒。

這是iOS8功能還是bug? 有沒有其他方法可以做到這一點?

ViewControllers呈現代碼。

從P,其中P是推動視圖控制器,

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

來自V1,

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

你可以使用你的V1嵌入NavigationController(NV)嗎? 這樣,你可以推動你的V2。 然后你可以彈出到V1或者將NV解雇到P.

花了很多時間研究結束后修補問題。

我做的是,在解除ViewController(V2)之前,我捕獲了一個ParentViewcontroller(P)的屏幕截圖並將其添加到應用程序窗口。 在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];
}];

當您關閉V1時調用'viewWill / DidAppear'的事實是合乎邏輯的,因為技術上V1在頂部viewController(V2)的模態解雇中暴露,如果只是足夠長的時間UIKit然后被賦予去除下一個底層viewController的任務(例如V1)。

我的猜測是iOS8中的V1視覺故障不是一個錯誤,更多的是關於iOS如何處理在iOS8中解雇模態內部模式。 由於沒有針對該情況的文檔,因此其實際行為可以合法地從iOS更改為iOS。

我認為一種方法可以做你想做的事情,保持你對舊iOS的向后兼容性,並使用具有記錄行為的API,將使用如下的代碼(可能作為UIViewController上的類別)。 動畫V1,然后簡單地刪除它(下面的#2)。 V2可能會使用標准的iOS'presentViewController'在V1內部動畫,但你也可以使用方法#1。

需要注意的是,由於您將V1.view作為子視圖添加到P而不是通過UIViewController模式系統,因此您將失去V1中的自動viewWill / DidAppear調用。 所以你需要手動調用它們。 在此示例中,它們在“animate up”類別方法中調用。

這不是我實際使用的代碼,但我過去做過類似的事情。 所以要小心一點,如果發現錯誤請發表評論....假設ARC:

希望這可以幫助。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM