I have an UIViewController having this method:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(#"DISAPPEAR");
lastKnownOrientation = [self interfaceOrientation];
}
-(void)openSendVC{
SendMsgViewController *vc = [[SendMsgViewController alloc]initWithNibName:#"SendMsgViewController" bundle:nil];
[self.navigationController pushViewController:vc animated:NO];
}
In the second view controller (SendMsgViewController) viewDidLoad I have the following:
[self presentViewController:picker animated:YES completion:NULL];
where picker is an UIImageViewPicker.
The problem is, when I call the method openSendVC a new controller is opened, but viewWillDisappear (of the first viewController) is not called.
That is the correct behavior. Here's an excerpt about viewWillDisappear: from the UIViewController API docs:
This method is called in response to a view being removed from a view hierarchy. This method is called before the view is actually removed and before any animations are configured.
Presenting a new view controller so that it hides the other view controller doesn't count as the view disappearing—only actually being removed from a view hierarchy does (e.g., with something like popViewControllerAnimated:).
Related
I have a programmatically created UIViewController named as "VC" and on top of that I need to load my existing UIViewController.
I used below code to do that, and it's working fine.
I can see my existing UIViewController on "VC" but not detecting any of viewDidAppear or viewWillAppear in existing view controller.
I am getting data from viewDidAppear and viewWillAppear so all the time my existing view controller collection view is empty.
ExistingViewController* presObj= [self.storyboard instantiateViewControllerWithIdentifier:#"oad"];
[vc.view addSubview:presObj.view];
[self addChildViewController:presObj];
[presObj didMoveToParentViewController:self];
Have you initialize the storyboard class?
self.storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
so all the time my existing ViewController collection view is empty --> are you using collection view in your code?
First you need to add the addChildViewController. Then add that childviewcontroller view into your main view.
Just add the [self addChildViewController:presObj]; before adding to the view subview.
ExistingViewController* presObj= [self.storyboard instantiateViewControllerWithIdentifier:#"oad"];
[self addChildViewController:presObj];
[vc.view addSubview:presObj.view];
[presObj didMoveToParentViewController:self];
Ok, If you are loading like this then your ViewDidLoad () of existing view controller will load, and you can put a condition (if needed) then you can call ViewDidAppear () ViewWillAppear() like below
existingviewcontroller *obj=[[existingviewcontroller alloc]init];
[obj viewWillAppear:YES];
[obj viewDidAppear:YES];
This will work
I have tab bar based application (iOS 7.1 SDK). When user start app at first time, I want show some login screen. I decided to use view controller containment (this is called in first view controller of tab bar controller):
LoginViewController *vc = [LoginViewController new];
[self.tabBarController addChildViewController:vc];
[vc didMoveToParentViewController:self.tabBarController];
[self.tabBarController.view addSubview:vc.view];
But there are some problems. View is normally visible, but in LoginViewController viewWillAppear and viewDidAppear are never called. I try to use this piece of code in all view lifecycle methods (viewDidLoad, viewWillAppear, viewDidAppear), but with no luck. I know there are some other ways to achieve what i'm trying to do. For example add child controller to first view controller of tab bar controller and hide tab bar, which works great and viewWillAppear and viewDidAppear are normally called. But because of this I get even more curious - why adding child view controller to tab bar controller don't work as expected?
You need to present or push the viewcontroller in order for the methods to get called. Just adding the view as a subview will not work.
In your case, you can explicitly call the viewWillAppear, viewDidAppear methods.
LoginViewController *vc = [LoginViewController new];
[self.tabBarController addChildViewController:vc];
[vc didMoveToParentViewController:self.tabBarController];
[self.tabBarController.view addSubview:vc.view];
[vc viewWillAppear];
[vc viewDidAppear];
It's working!
dispatch_async(dispatch_get_main_queue(), ^{
[self.tabBarController setSelectedIndex:0];
[self.tabBarController setSelectedIndex:1];
[self.tabBarController setSelectedIndex:0];
});
I have a HomeView and a HomeDropDownView.
HomeDropDownView is shown as a drop-down view over the HomeView.
HomeView is a delegate of HomeDropDownView.
When I do an action in HomeDropDownView I want to call a delegate method in HomeView and have that delegate method present a third view controller, TestViewController from it's navigation controller.
If I try to launch TestViewController from anywhere in the class it works fine - except from the delegate method.
There are animations in HomeDropDownView but putting the call to the delegate method in the complition does not make the view controller appear. And in the case that I'm using this the animation's don't fire anyway; there's only a resizing without animation.
TestViewController's init does get called as well as the viewDidLoad but not the viewWillAppear and the view dose not appear.
Code:
HomeDropDownView
- (void)finalAction {
...
[self callDelegateAction];
...
- (void)calldelegateAction {
if ([self.delegate respondsToSelector:#selector(launchTestView)] ) {
[self.delegate launchTestView];
} else {
DLog(#"Error out to the user.");
}
}
HomeView
- (void)launchTestView {
//[self listSubviewsOfView:self.parentViewController.view];
NSLog(#"delegate method | self: %#", self);
TestViewController *tvc = [[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
//[self.navigationController presentViewController:tvc animated:YES completion:nil];
//[self.view.window.rootViewController presentViewController:tvc animated:YES completion:nil];
//[self.navigationController pushViewController:tvc animated:YES];
AppDelegate *appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appdelegate.tabBarController.navigationController presentViewController:tvc animated:YES completion:^() {
NSLog(#"Done!");
}];
}
None of the above approaches work. But if I put the exact same code into the viewDidAppear or put it in a button action method, it will work fine. At the time of calling the delegate method's self is HomeView and all the subviews, including the nav controller do seem to be there. This is in a tabcontroller-based project but I think that any of the above are acceptable ways to call the nav controller still.
What am I missing? Why does my delegate method not want to push/present a viewcontroller on HomeView's Nav controller? It's probably something I'm missing but I can't find a reason in the Apple Docs or any other thread.
Thanks for the help!
Sadly this turned out to be that HomeView was being changed underneath the execution of the message. So by the time the HomeView got the message call it was no longer the same HomeView object that had requested action in the first place. So it was not the same delegate.
This was done so that it would appear to the user that the same view was being used for different things.
But this is a good example of why you should not destroy and re-create critical views. We should have been using the same view and reloading the objects instead if we knew that we would be sending messages. Or had some notion of a control structure.
I have a view controller B in a parent view controller A. Both views are showing the same time.
In view controller B, I'm trying to present a new view controller using the following method:
- (void) buttonClicked:(id)sender
{
MyViewcontroller *vc = [[MyViewcontroller alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
The view controller appears correctly in iOS6 and I dismiss MyViewController by using the following method:
- (IBAction)backButtonPressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
But there is a difference between iOS 5.1 and iOS 6.
QN1: Upon dismissal, view controller A & B viewDidAppear are not invoked. Is it supposed to be triggered?
QN2: I can't get MyViewController to show up in iOS 5.1.1. unless I add view controller B as a child container to A:
[self addChildViewController:vcB];
[self.view addSubview:vcB.view];
By adding the child controller, I can get MyViewController to show and view controller A&B viewDidAppear will be called when it gets dismissed. viewDidAppear also gets called when using iOS6.
I'm not sure what is going on here.
Answer 1 : viewDidAppear will not be called when you dismiss a modal view.
Answer 2 : if you are presenting "MyViewController" from "View-controller B" then View-controller B's view should be in view hierarchy.
From here you can get more information. How to Presenting View Controllers from Other View Controllers
The thing is: I have a modalViewController presented with a button that triggers an IBAction like this:
-(IBAction)myMethod
{
[self dismissModalViewControllerAnimated:YES];
if([delegate respondsToSelector:#selector(presentOtherModalView)])
{
[delegate presentOtherModalView];
}
}
in the root view that is the delegate for that modalViewControllerI've implemented the presentOtherModalView delegate method and it looks like this:
-(void)presentOtherModalView
{
AnotherViewController *viewInstance = [[AnotherViewController alloc]initWithNibName:#"AnotherViewController" bundle:nil];
viewInstance.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:viewInstance animated:YES];
[viewInstance release];
}
The problem is this second modalViewController is not being presented. It gives me the message wait_fences: failed to receive reply: 10004003... How should this be done?
Because they are executed exactly after each other (they don't wait for the view to disappear/appear), it doesn't get executed. Because there can only be one ModalViewController on the screen at a time, you have to first wait for the other ModalViewController to disappear before the next one is put on screen.
You can do this creatively how you want, but the way I did it was something like:
[self dismissModalViewControllerAnimated:YES];
self.isModalViewControllerNeeded = YES;
And then in the underlying ViewController, in the viewDidAppear method, I do this:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.isModalViewControllerNeeded) {
[self presentModalViewController:viewInstance animated:YES];
self.isModalViewControllerNeeded = NO;
}
}
Hope it helps!
It is because the dismissModalViewControllerAnimated takes some time to dismiss with animation and you are calling another view to present as modal view before dismissing the 1st modal view so the presenting modal view call was rejected. You should not perform animations when you are not on the view after completely dismissing only you can call another view. To solve this problem call the present modal view after 2 or 3 seconds using time interval or use completion block for dismissModalViewControllerAnimated
You can achieve it by using this
[delegate performSelector:#selector(presentOtherModalView) withObject:nil afterDelay:3];