Working with local push notifications if the notification receives its move to NotificationViewcontroller there is no notification it moves the main view controller .
Here I'm using code:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
if ([status isEqualToString:#"YES"])
{
NotificationViewcontroller *notify_view =[[NotificationViewcontroller alloc]init];
[self.window.rootViewController presentViewController:notify_view animated:YES completion:nil];
when i use this code means it should not move to NotificationViewcontroller i got this errorr:
whose view is not in the window hierarchy!`
// self.window.rootViewController=notify_view;
i use this code it move to NotificationViewcontroller. after seeing the notification put one back button to go view controller
NSLog(#"Go to some other view");
}
else
{
[self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
}
After see the notification put one back button to go view controller that back button is not working.
-(IBAction)back_btn:(id)sender
{
[self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
}
You are setting the rootviewcontroller as NotificationViewcontroller , so on press of back button change the rootviewcontroller as some other view controller.
Because there is no view hierarchy, to dismiss the view controller.
presentviewcontroller is used to open new viewcontroller from existing viewcontroller, then only you can dismiss your presentedviewcontroller and it will go back to your parent(e.g.) viewcontroller.
Related
I launch a modal view controller VCM embedded in a Navigation controller from VC1.
The modal VC has a button to go to another View Controller, VC2.
if the user presses the button to go to VC2, I need to simultaneously dismiss the modal and also change the sending from VC1 to VC2. (It's important to dismiss the modal to get rid of it, so I don't have VCs accumulating on the stack.)
Here is the action method in the modal attached to the VC2 button.
- (IBAction)VC2ButtonPressed:(id)sender {
[self dismissViewControllerAnimated:true completion:nil];
//Above line works fine
[VC1 performSegueWithIdentifier:#"showVC2" sender:VC1];//No known class method error
}
I can dismiss the modal without any problem (first line) but can't figure out how to simultaneously segue to VC2. There is a storyboard segue in VC1 named 'showVC2' for what it's worth. I do not have any relevant class methods currently in the sending VC. Should I create a special class method? Or how can I invoke a method in the VC that launched the modal.
Edit:
I also tried:
[self.presentingViewController performSegueWithIdentifier:#"showVC2" sender:self];
This compiles but gives runtime error () has no segue with identifier 'showVC2''
I think this is because VC2 is embedded in a tabbarcontroller.
Edit2:
I tried putting code in completion handler as suggested by #Oscar but while code gets fired, VC2 does not load
[self dismissViewControllerAnimated:YES completion:^{
[self gotoVC2];
}];
new method
-(void)gotoVC2 {
LogDebug(#"gotoVC2 called");//DOES log to console
UIStoryboard *storyBoard = self.storyboard;
IDFeedVC *VC2 =
[storyBoard instantiateViewControllerWithIdentifier:#"vc2"];
[self presentViewController:VC2 animated:YES completion: nil];
}
Thanks for any ideas.
I am now using the tabbar controller and the uinavigation controller, when I call the MFMailComposeViewController by presentviewcontroller, and dismissed by dismissviewcontrolleranimated, I swipe back and click to push the viewcontroller again I found the back button is disappear and the title is wrong.
Tab-> ViewController [A] (Navigation Controller Embed) -(PUSH)-> ViewController[B] (with back button) -(Present)-> MFMailComposeViewController -(Dismiss)-> Show ViewController[B] -(Swipe Back)-> ViewController [A] -(Push) -> ViewController[B] (back button is disappear and the title is wrong)
Even I press back instead of swipe back, I found that there is still some problem not behave as usual navigation push controller
Many thanks if anyone could help!
After all these, ViewController[B] pop/swipe back to ViewController[A] viewdidappear and viewwillappear function in ViewController[A] are not triggered.
I have the exact same flow in my app, but I don't have any problem with the nav bar getting messed up.
Here's how the view controller is created:
MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
The delegate is set:
mailVC.mailComposeDelegate = self;
The view controller is presented:
[self presentViewController:mailVC animated:YES completion:nil];
The view controller is dismissed in the delegate method which is called when the user presses the Cancel button in the nav bar:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Hope this helps.
Let say I have view controllers named A,B,C,D,E I open theseViewConrollersone after the other in presentModel way. When I am in ViewController E I want to open another ViewController F in presentModel way. In that F ViewController I have a back button. When I click on that It should dismiss the F and show the A ViewController. But now when it dismissse shows E. How can I dismiss all other viewcontrollers except the A when I click the back button of F
Please help me. Thanks
UPDATED
-(IBAction)dismisthis:(id)sender{
UIViewController *dismissingViewController = self.presentingViewController;
while (dismissingViewController.presentingViewController != nil && [dismissingViewController isKindOfClass:[FrontViewController class]]) {
dismissingViewController = self.presentingViewController;
}
[dismissingViewController dismissViewControllerAnimated:NO completion:NULL];
If you dismiss a view controller that is presenting another view controller, the entire hierarchy is dismissed. It doesn't matter how many levels there are. So all you have to do is find your view controller A and tell it to dismiss its presented view controller.
If A is always the bottom of the heap, you can use a simple loop to find it:
UIViewController *dismissingViewController = self.presentingViewController;
while (dismissingViewController.presentingViewController != nil) {
dismissingViewController = self.presentingViewController;
}
[dismissingViewController dismissViewControllerAnimated:YES
completion:NULL];
What about sending Notification using NSNotificationCenter from F and A will listen to it. Once A receives the notification, it will call dismissViewController which I think will dismiss all.
At this moment i can think of three solutions
You should keep track of all viewControllers in a stackObject(which is an array) in Appdelegate. When you want it access this get these array and dismiss all view controler objetcs.
Each viewcontroller you can observer for a NSNotification which will listen for notification. When you need it in "F" just post the notification and this notification will dismiss the eviewcontrollers
Go for NavigationController so that you can push to rootviewcontroller
Try this:
UIViewController *rootVC = [UIApplication sharedApplication].delegate.window.rootViewController;
[rootVC dismissViewControllerAnimated:YES completion:nil];
// One-liner
// [[UIApplication sharedApplication].delegate.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
Make A as rootViewController and use below code on Back button of "F":
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:true completion:nil];
I have a structure about navigation and many page have modal (popup) on the uiviewcontroller(UINavigationController).
When I disconnect the bluetooth, I need back to the root the viewcontroller.
So I set the dismiss and popToRoot in the disconnect method
-(void) disconnect
{
....
[appDelegate.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
NSLog(#"appDelegate.window.rootViewController:%#",appDelegate.window.rootViewController.class);
// show log appDelegate.window.rootViewController:UINavigationController
[appDelegate.window.rootViewController.navigationController popToRootViewControllerAnimated:YES];
....
}
But when I run the program and disconnect bluetooth,
In the case 1: modal the viewcontroller showing,
It will dismiss the modal viewcontroller, the dismiss was correct.
But there are not back to the root navigation controller after dismiss modal viewcontroller.
In the case2: just in the uinavigation controller page.
when I disconnect the bluetooth, there are not back to the root navigation controller.
How can I back to the navigation root page?where are my fails?
thank you very much.
// ------ answer -------
change code to
[appDelegate.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
[self performSelector:#selector(gotoRoot) withObject:nil afterDelay:0.50];
- (void) gotoRoot {
UINavigationController *myNavCon = (UINavigationController*)appDelegate.window.rootViewController;
[myNavCon popToRootViewControllerAnimated:YES];
}
From the class you presented your modal view call dismiss of modal and then perform selector after some delay and then do the here is the sample code
- (void) dismissAndGoToRoot {
[self dismissViewControllerAnimated:YES completion:nil];
[self performSelector:#selector(gotoRoot) withObject:nil afterDelay:0.50];
}
- (void)gotoRoot {
[self.navigationController popToRootViewControllerAnimated:NO];
}
From apple developer documentation about dismissViewControllerAnimated:completion:
completion: The block to execute after the view controller is dismissed. This block has no return value and takes no parameters. You may specify nil for this parameter.
So I think this is better solution
[self dismissViewControllerAnimated:YES completion:^(){
[self.navigationController popToRootViewControllerAnimated:NO];
}];
Using completion block is better than afterDelay. How do you choose the good delay ? What happens if too short ? If too long, execution code waits for nothing ...
I am developing an app that as first viewcontroller has an UIViewController.
This controller pushes a NavigationViewController that contains other controllers.
Now I need to pop the RootViewController of the NavigationController to go back to the initial UIViewController.
I tried with
[self dismissViewControllerAnimated:YES completion:nil];
and the app crashes("Tread1:EXC_BAD_ACCESS(code=1, address= ......)").
I tried with
[self.navigationController popViewControllerAnimated:YES];
and nothing happens.
The initial UIViewController calls
[self performSegueWithIdentifier:#"MyIdentifier" sender:self];
In the UIBuilder the segue is of type "Show(e.g. Push)"
Then I have a NavigationViewcontroller that contains the RootViewController and another Viewcontroller.
What I am trying to achieve is to go back to the first viewcontroller (the one outside the navigationcontroller) from the RootViewController. So I should have the navigationcontroller there.
What am I missing?
Apparently I had a couple of GestureRecognizer still in place that were causing the crash of the app.
The right method was:
[self dismissViewControllerAnimated:YES completion:nil];