I'm facing issue with redirecting the viewControllers using pop/pushViewControllers. I've three view controller like below image -
In my 3rd view i've some ToggleButton based on that toggleButton the data which is in 2nd View will change. After, changing something on 3rd view and press Done button in my 3rd View i just started my 2nd ViewController using pushViewController And, the changes are occured successfully.
But, what was the issue is, when i try to press the back button on my 2nd view page its redirecting me again to 3rd viewController (Because of pushViewController)
I try to start my 2nd view using popViewController but, its giving exception.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.
I've used below code -
SecondViewController *second = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
second.array = resultArray;
second.indexValue = ind;
[self.navigationController popToViewController:second animated:YES];
How do i solve this issue? Any idea?
From 3rd viewcontroller you just need to call this method to pop to 2nd viewcontroller :
[self.navigationController popViewControllerAnimated:YES];
EDIT :
For notifying the second vc for data change you can use delegate. Follow this :
On ThirdViewController.h
#protocol DataChangeProtocol;
#interface ThirdViewController : UIViewController
#property(nonatomic,assign) id<DataChangeProtocol> delegate;
#end
#protocol DataChangeProtocol
- (void)thirdViewcontroller:(ThirdViewController*)vc dataChangedto:(NSDictionary *)changedData;
#end
And before pushing the thridVC from secondVC assign secondVC as the delegate of thirdVC :
ThirdViewController *thirdVC = [[ThirdViewController alloc]init..];
thirdVC.delegate = self;
[self.navigationController pushViewController:thirdVC animated:YES];
and in SecondViewController.m
- (void)thirdViewcontroller:(ThirdViewController*)vc dataChangedto:(NSDictionary *)changedData {
// Change your values in the UI using the passed value from changedData.
}
You create our viewcontroller:
SecondViewController *second = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
and then you want to pop it from your stack but this controller is not in the stack, bacause you create it in the third viewController.
//it used in first class
SecondViewController *second = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
second.array = resultArray;
second.indexValue = ind;
[self.navigationController pushViewController:second animated:YES];
//it move to second class
//it used in second class
[self.navigationController popViewControllerAnimated:YES];
//it move to firsr class
If you want to go to your current previous view controller then you have to do this:
[self.navigationController popViewControllerAnimated:YES];
Related
I have 2 storyboard files in my app and I'd like to transition between a ViewController in one to a ViewController in the other. I've hooked up an IBAction in response to a button press on the first ViewController, which calls a method in the AppDelegate. I have verified that this signal reaches the AppDelegate method.
Here is the relevant method I have in the AppDelegate, however, no transition occurs. Can anyone tell me why, or is it a silly idea to have 2 storyboards?
-(void) presentSecondViewController {
UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController* mainViewController = [mainStoryboard instantiateViewControllerWithIdentifier:#"main_viewcontroller"];
UIStoryboard* secondStoryboard = [UIStoryboard storyboardWithName:#"SecondStoryboard" bundle:nil];
UIViewController* secondViewController = [secondStoryboard instantiateViewControllerWithIdentifier:#"second_viewcontroller"];
[mainViewController presentViewController: secondViewController animated:YES completion: NULL];
}
You create a second instance of the initial view controller of the first storyboard. That instance was never shown on the screen as it is different from the one being already shown and thus probably won't show your second view controller. You need the instance of the view controller already being shown. The best way would be to change your implementation to
-(void) presentSecondViewControllerFromViewController:(UIViewController *)sourceController
{
UIStoryboard* secondStoryboard = [UIStoryboard storyboardWithName:#"SecondStoryboard" bundle:nil];
UIViewController* secondViewController = [secondStoryboard instantiateViewControllerWithIdentifier:#"second_viewcontroller"];
[sourceController presentViewController: secondViewController animated:YES completion: NULL];
}
and call it by passing the view controller that contains the button.
I have an App with one MainWindow.xib file. Then I have ViewControllerA.xib and ViewControllerB.xib. My MainWindow.xib have one ViewController that points two ViewControllerA.xib.
On ViewControllerA I have a button and I would like the button, when pressed, to move ViewControllerB onto the screen. How do I do that?
I tried this code, but I think I am missing something:
- (IBAction)btMyButton:(id)sender
{
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
[self.navigationController pushViewController:viewController animated:YES];
}
My ViewControllerB does appear, but it is squashed at the top of the screen, over the previous view. Any help is greatly appreciated.
Thank you
Remove the second line:
[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
You are adding the view twice. The 2nd and 3rd lines both cause the view to be added to the view hierarchy in different places.
--update--
If you remove the 2nd line and are not seeing your view then self.navigationController is most likely nil. Try [self presentModalViewController:] instead.
Make sure that the view of controller B has correct hight you should subtract the navigation bar height 44 px and status bar 20 px as well. Those values are for iPhone.
- (IBAction)btMyButton:(id)sender
{
//you should load from the main app bundle
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:[NSBundle mainBundle]];
// you don't need the following line
//[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
}
Update
As the above comment says if you may don't have a navigation controller to push Controller B into. So Add a navigation controller into the main window instead of the view controller and make its root view controller you Controller A.
I hope this helps you,
you will need to remove old viewcontroller from main windows.
- (IBAction)btMyButton:(id)sender
{
//Assuming you declare two Iboutlet controllerA, controllerB mapping with that view as class variable
{
if (self.controllerB == nil)
{
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
self.controllerB = viewController;
[viewController release];
}
[controllerA.view removeFromSuperview];
[self.view insertSubview:controllerB.view atIndex:0];
}
}
I have app with UITabBarController. First tab has UINavigationController and it is UITableViewController. I mean I have tabs at the bottom and in first tab I have a table with possibility to navigate to other views. After touching one of cells I call view with MKMapView
if([indexPath section] == 3){
LocationDetailViewController *dvController = [[LocationDetailViewController alloc] initWithNibName:#"LocationDetailView" bundle:[NSBundle mainBundle]];
dvController.locationGPS = self.locationGPS;
[self.navigationController pushViewController:dvController animated:YES];
LocationDetailViewController is defined like
#interface LocationDetailViewController : UIViewController <MKMapViewDelegate>
in it I have a toolbar with button with action:
- (void)myCurrentAddress:(id)sender {
AddressDetailViewController *dvController = [[AddressDetailViewController alloc] initWithNibName:#"AddressDetailView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES]; }
AddressDetailViewController is defined like:
#interface AddressDetailViewController : UIViewController
When I try to use code:
- (void)myBackAction {
[self.navigationController popViewControllerAnimated:YES]; }
it doesn't do anything. Debugger stops on this line - and then continues with no warnings or errors - but no changes on screen. If i remove my own back button and standard back button will be generated it will navigate back NavigationBar but not the view.
Also if I navigate to AddressDetailViewController from another tableviewcontroller class then eveyrhing is ok, where you should look into to find out the problem? please help ))
stupid me i had
- (void)viewWillDisappear:(BOOL)animated {
[self.navigationController popViewControllerAnimated:NO];
in LocationDetailViewController - after removing it everything is ok, sorry )
I am fairly new to iPhone. I have a peculiar problem. I am adding a view controller as a subView to the current view. And then I want to push a new view controller from it. The problem is when I try to do pushViewController, it is not responding.
For example, in CurrentViewController I have added NewViewController's view as subView
[self.view addSubView : NewViewController.view]
Now From NewViewController, on the click of a button I am doing the following :
SecondViewController *secondVC = [SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondVC animated:YES];
Here the secondVC doesn't get pushed to the stack.
If you have used view based application, You have to use this code.
SecondViewController *secondVC = [SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
// [self.navigationController pushViewController:secondVC animated:YES];
[self presentModalViewController:secondVC animated:YES];
If you want to use navigation controller in your appln. First you have to add navigation controller in your appln and then only will navigate the view.
Perhaps the problem is that method is called pushViewController not pushToViewController. Try
SecondViewController *secondVC = [SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondVC animated:YES];
// don't forget release here
[secondVC release];
here's my code:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
[self.navigationController presentModalViewController:vc animated:YES];
//[self setView:[vc view]];
If I call it, nothing happens. However, if I change it to:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
//[self.navigationController presentModalViewController:vc animated:YES];
[self setView:[vc view]];
The view appears just fine (without the transition, of course).
What am I doing wrong? Is there anything special you have to take care of when initializing the view controller? I tried to copy as much as possible from Apple's examples, but I can't get this to work...
Thanks for any input!
-- Ry
You can only present modal view controllers from controllers that have already been shown onscreen (usually through a UINavigationController or UITabBarController). Try creating a UINavigationController, pushing a viewController to it, and then presenting your modal controller. There's a starter project in Xcode that shows how to create a UINavigationController-based flow if you're unfamiliar with it.
One other thing to note: if you haven't pushed the view controller onto a UINavigationController, the .navigationController property will be nil, and messaging it will have no effect.
I encountered the same problem while attempting to show a modal view over another modal view. Ben's answer is correct, and can be implemented like so:
#interface FirstView: UIViewController {
UIViewController *firstView;
}
- (IBAction)showOptionsView:(id)sender;
#end
In the main view class:
- (void)viewDidLoad {
[super viewDidLoad];
firstView = [[UIViewController alloc]init];
[firstView setView:self.view];
[firstView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
}
- (IBAction)showOptionsView:(id)sender {
OptionsView *optView = [[OptionsView alloc]initWithNibName:#"OptionsView" bundle:nil];
if(firstView != nil) {
[firstView presentModalViewController:optView animated:YES];
[optView release];
}