ViewDidAppear calls the view manager, which is rejected in iOS8

Suppose ParentViewcontroller is P, FirstViewController as V1 and SecondViewController as V2.

I represent V1 from P, then V2 from V1. Now I want to go directly to P. For this, I use

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

This works great in iOS7. But in iOS8 I run into a problem (I don't know if this is a problem or not) at the same time. This V1 method viewDidAppear is called, as well as its kind of crashes on the screen for a second.

Is this a feature or bug of iOS8 ?. Is there an alternative way to do this?

ViewControllers representing the code.

From P, where P is the pushed view controller,

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

From v1,

 ViewController2 *v2 = [[ViewController2 alloc] init]; [self presentViewController:v2 animated:NO completion:nil]; 
+5
source share
3 answers

Can you use the built-in V1 in the NavigationController (NV)? So you can press V2. You can then put in V1 or reject NV to P.

0
source

After spending a lot of time researching, he fixed the problem.

I did this before rejecting ViewController (V2), I captured a screen shot of ParentViewcontroller (P) and added it to the application window. Then remove the image from the window after dismissing the 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
source

The fact that 'viewWill / DidAppear' is called when you reject V1 is logical, since technically V1 is displayed in modally firing the top viewController (V2), unless long enough so that UIKit then performs the task to remove the next base viewController (e.g. V1).

I assume that the visual glitch V1 in iOS8 is not a mistake and is more related to how iOS deals with firing the modal intra-modal in iOS8. Since no documentation exists for this situation, its actual behavior can legitimately change from iOS to iOS.

I think that one of the ways to do what you want to do, to maintain backward compatibility with older iOS and use the API with documented behavior, will use the code, for example, below (perhaps as a category on the UIViewController). to animate V1 up and then just delete it (# 2 below). V2 could probably be animated inside V1 using the standard iOS 'presentViewController', but you can also use method # 1 for it.

One point is that since you add V1.view as a subtask in P instead of using the modal UIViewController system, you will lose automatic access to viewWill / DidAppear in V1. Therefore, you will need to call them manually. In this example, they are called in a method of the Animation Up category.

This is not the code I use, but in the past I have done similar things. Therefore, be careful and comment if errors are found .... suggests ARC:

Hope this helps.

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

Source: https://habr.com/ru/post/1205101/


All Articles