navigation issue between viewcontrollers - objective-c

After pushing a viewcontroller, when I want to pop it back my application is crashing.
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count>0) {
[[self navigationController] popViewControllerAnimated:YES];
}
the controller I'm pushing, has uiwebview and for the requirement I m doing
[twebView stopLoading];
I'm clueless. anyone please give me a good working suggestion.
and is there any easy way to pushviewcontroller from right to left??

First alloc your array first. Refer following code:
NSArray *viewControllers = [[NSArray alloc]init];
viewControllers = self.navigationController.viewControllers;
NSLog(#"Controllers = %#",viewControllers);
if (viewControllers.count>0) {
[[self navigationController] popViewControllerAnimated:YES];
}
And also check log of controllers as above.

for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[OldViewController class]])
{
//Do not forget to import AnOldViewController.h
[self.navigationController popToViewController:controller animated:YES];
break;
}
}

Related

Instance variables not working in ViewController in UINavigationController

I'm still new to iOS development but I've ran into a problem that I can't solve and I've tried looking online but can't find anything yet.
I'm using a UIImagePickerController to pick and image and I'm using it in the App Delegate. When an image is returned, in the imagePickerController:didFinishPickingMediaWithInfo method, I want to make a new navigation controller with a view controller and put it over the "app".
Here is how I'm doing it:
CustomNavigationController *customNavigationController = [[CustomNavigationController alloc] init];
PhotoViewController *photoViewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:[NSBundle mainBundle]];
[customNavigationController pushViewController:photoViewController animated:NO];
[customNavigationController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
[photoViewController release];
[self.window addSubview:customNavigationController.view];
//Call method of photoViewController.
[[customNavigationController.viewControllers objectAtIndex:0] addPhotoFromData:info];
[self.tabBarController dismissViewControllerAnimated:YES completion:nil]; //Get rid of UIImagePickerController
However in the photoViewController, I don't have access to any instance variables synthesized and loaded in viewDidLoad. They all return to null. There is also a tableView and calls to reload the tableView do not actually cause the tableView to respond.
Here is some of the code from photoViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.photoCount = 0;
self.timestamp = [[NSDate date] timeIntervalSince1970];
self.photos = [[NSMutableArray alloc] initWithCapacity:5];
self.photosData = [[NSMutableArray alloc] initWithCapacity:5];
self.uploadingCount = 0;
UINib *customCell = [UINib nibWithNibName:#"CustomTableCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:customCell forCellReuseIdentifier:#"customCell"];
self.tableView.separatorColor = [UIColor clearColor];
NSLog(#"%#", self);
}
and also the addPhotoFromData method:
- (void)addPhotoFromData:(NSDictionary *)info
{
[self.photos addObject:info];
NSLog(#"%#", self.photos); //Doesn't add "info" and does not return anything when later called from other methods.
[self.tableView reloadData]; //Doesn't work
Everything was working before I add in the UINavigationController. I'm completely lost.
EDIT: After some more debugging attempts, I have discovered that the view is not loaded when addPhotoFromData is called. viewDidLoad is called afterwords. Is there a way to delay method calls?
Any reason you can't have the PhotoViewController call addPhotoFromData: inside the viewDidLoad method? You can always access properties of the app delegate from the view controller:
YourAppDelegateType * delegate = [UIApplication sharedApplication].delegate;
[self addPhotoFromData:delegate.info];

How do I push many Views from one View using UINavigationController

I code many transition App using UINavigationController.
This is my transition image
"Main"-->"Second"-->"Third"-->"Fourth"
"Second"-->"A"-->"B"
"Second"-->"C"
"Third"-->"D"
"Main" is RootViewController.
At No2 and No3, if (["boo" isEqual:"foo"]){transit "A"} else if ("boo"...){transit "C"}.
I could make "Main" to "Forth", No.1 transition.
like this
ThirdViewController *thirdView = [[ThirdViewController alloc] init];
[self.navigationController pushViewController:thirdView animated:YES];
But I can't make "Second" to "A"and "B".
I thought to set UIRootViewController to "Second".
But "Second" needs to transit "A" and "C".
at "Second" like this...
SecondViewController.m
AViewController *aView = [[AViewController alloc] init];
[self.navigationController pushViewController:aView animated:YES];
How can I code?
Thank you! And sorry in poor English.
Please help me!
NSInteger index = 0;
for (UIViewController *view in self.navigationController.viewControllers) {
if([view.nibName isEqualToString:#"RootViewController"])//put any `XIB name` where u want to navigate
break;
index = index + 1;
}
[[self navigationController] popToViewController:[[self.navigationController viewControllers] objectAtIndex:index] animated:YES];
Try this code to push to a controller
DrawImgViewcontroller *ObjImageViewController = [[DrawImgViewcontroller alloc] initWithNibName:#"DrawImgViewcontroller" bundle:nil];
[self.navigationController pushViewController:ObjImageViewController animated:YES];
[ObjImageViewController release];
and use below code to go back
[self.navigationController popViewControllerAnimated:YES];
and use this to any controller you like
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:NO];//Instead of one you can use the currect index you need

How do I switch a new view controller in iOS development?

I am trying to write an IBAction to switch view controllers for my iPhone application:
-(IBAction)changeToView2:(id)sender
{
if (self.view2 == nil)
{
view2 = [[UIViewController alloc] initWithNibName:#"View2Controller" bundle:[NSBundle mainBundle]];
}
self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentedViewController: view2 animated:YES];
}
However, I am getting a build error noting that no interface declares "presentedViewController:animated:". Why?
Changing this to "presentViewController:animated:" produces the same error.
The method is presentViewController:animated:completion:, not presentedViewController:animated:
Instead of
[self presentedViewController: view2 animated:YES];
try
[self presentViewController: view2 animated:YES];
[self presentViewController:view2 animated:YES];
Try this your edited code.I think this will be helpful for you.
-(IBAction)changeToView2:(id)sender
{
if (self.view2 == nil)
{
view2 = [[UIViewController alloc] initWithNibName:#"View2Controller" bundle:nil];
}
self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentedViewController: view2 animated:YES];
}

Is it Possible to call PopViewControllerAnimated and PushViewController for single click event

On a buttonclick action I want to destroy the current screen at the same time I want to navigate it to home screen instead of previous screen.
I tried to do that by Putting this code but didn't work.
-(IBAction) sel_goback
{
[self.navigationController popViewControllerAnimated:YES];
Home1ViewController *HM = [[Home1ViewController alloc] initWithNibName:#"Home1ViewController" bundle:nil];
[self.navigationController pushViewController:HM animated:YES];
[HM release];
}
If self is the top view controller, then by the time popViewControllerAnimated: has returned, self.navigationController has been set to nil. Try this:
-(IBAction) sel_goback
{
UINavigationController *nav = self.navigationController;
[nav popViewControllerAnimated:YES];
Home1ViewController *HM = [[Home1ViewController alloc] initWithNibName:#"Home1ViewController" bundle:nil];
[nav pushViewController:HM animated:YES];
[HM release];
}
However, "home screen" sounds like something that would already be on your navigation controller's stack. Maybe what you really want is something like this:
-(IBAction) sel_goback
{
UINavigationController *nav = [self.navigationController];
while (nav.viewControllers.count > 1 && ![nav.topViewController isKindOfClass:[Home1ViewController class]])
[nav popViewControllerAnimated:YES];
if (![nav.topViewController isKindOfClass:[Home1ViewController class]]) {
Home1ViewController *home = [[Home1ViewController alloc] initWithNibName:#"Home1ViewController" bundle:nil];
[nav setViewControllers:[NSArray arrayWithObject:home] animated:YES];
}
}

Check if controller has already been loaded XCode

I have the following code to push a new ViewController in a Split View Controller:
Level4ViewController *controller = [[Level4ViewController alloc] initWithNibName:#"ModuleViewController" bundle:nil];
[[detailViewController navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
The only problem I have, if I were to run this again, a new controller will show, I would like to be able to go to the view that I had before with all my data.
Can anyone help me out here.
Thanks.
EDIT:
Updated code?
Level4ViewController *controller;
for(UIView *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[Level4ViewController class]])
{
controller = view;
if(controller == nil)
{
controller = [[Level4ViewController alloc] initWithNibName:#"ModuleViewController" bundle:nil];
}
else {
controller = [self.navigationController.viewControllers objectAtIndex:1];
}
}
}
[[detailViewController navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
UINavigationController has a property viewControllers which is a NSArray that hold all the stack that has been pushed to the navigation controller, in this array you can check for your view controller if it is there use that one - you check like this -
Level4ViewController *lvc;
for(UIView *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[Level4ViewController class]])
{
lvc = view;
}
}
and if you already knows that at which index your viewcontroller is there then you can get it from that index as -
Level4ViewController *lvc = [self.navigationController.viewControllers objectAtIndex:1];
update -
Level4ViewController *controller;
for(UIView *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[Level4ViewController class]])
{
controller = view;
}
}
if(controller == nil)
{
controller = [[Level4ViewController alloc] initWithNibName:#"ModuleViewController" bundle:nil];
}
[[detailViewController navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
If you are using a navigation controller
FirstScreenViewController *firstScreenVC = [self.storyboard instantiateViewControllerWithIdentifier:#"1S"];
if (![self.navigationController.topViewController isKindOfClass:FirstScreenViewController.class])
[self.navigationController pushViewController:firstScreenVC animated:YES];