push last view from UIViewCOntroller - uitableview

Hi guys i have quick question, So i have uset UIViewController to push some views on my window based application and
here is the question:
Accessibility_view_Controller * accessibility_controller = [Accessibility_view_Controller alloc];
accessibility_controller.path_for_save = self.path_2;
accessibility_controller.Supporters_survey = [ self.Supporters_survey_mut objectAtIndex:row_value];
accessibility_controller.Supporters_info = [self.Supporters_info_mut objectAtIndex:row_value];
[self.navigationController pushViewController:accessibility_controller animated:YES];
[accessibility_controller release];
i am on the accessibility_controller view now but i want to move back to the view from where i called this, i mean the parentview , i know i can do it from navigation bar but i want to do it from tapping a row. SO what will be the code for pushing the parent view controller of the accessibilty controller on the window. .

Just use [[self navigationController] popViewControllerAnimated:YES]; to go back. This is very well documented here

Related

Add Animation to View Change

So after a lot of research if finally found the code that allows me to change to another view without giving me any errors:
UIViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"gameOverPage"];
[[[[UIApplication sharedApplication] delegate] window] setRootViewController:vc];
The only problem with this code is that there is no animation. I want to somehow add the cross dissolve animation to this if possible.
Another major problem is that it shows the view two times (some times three). So it goes to the second view and then less than a second later, it shows the page again. I know this because iAd is reloaded and when I press a button that goes to another page, it is interrupted by the second page coming up again.
To change the view to another (navigating) you don't need to setRootViewController: set it as root view controller always.
you can use a UINavigationController and set a UIViewController as root, then to change view use pushViewController: method of navigation controller, like
//Pre condition - already a viewController is root view controller of navigation controller.
UIViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"gameOverPage"];
[self.navigationController pushViewController:vc animted:YES];
Another way is,
[self presentViewController:vc animated:YES completion:nil];
Read more presentViewController, UINavigationController

How to switch between view controllers and get rid of the previous one

In android, switching between activities, is fairly straightforward
you call
Intent intent = new Intent(this,NextActivity.class); <- define the next activity
startActivity(intent); <- start the next activity
finish(); < -get rid of the current activity
now in iOS i know how to do this:
UIViewController *nextviewcontroller = [[UIViewController alloc]initWithNibName:#"nextvc" bundle:nil];
[self presentViewcontroller:nextviewcontroller animated:YES completion:nil];
How do I get rid of the current view controller? so that currentviewcontroller dies after presenting nextviewcontroller ?
[self dismissViewController:YES]; doesnt seem to do the trick
the lifecycle methods viewWillDisappear and viewDidDisappear are called even if I don't call [self dismissViewController:YES];
i want "currentviewcontroller" to be removed from the memory, and from the viewcontroller stack, so that clicking "back" in "nextviewcontroller" will go to some thirdviewcontroller that was before currentviewcontroller
In iOS is different, since there's no concept of Activity and everything is more focused on the app itself (in Android you can mix activities from different apps). Therefore, there's no concept of "view controller stack".
The most similar concept is the "navigation stack" of navigation controllers, where you actually push and pop new view controller into some kind of linear navigation. A navigation bar is automatically created and populated with back buttons.
presentViewController will show your view controller modally upon the current one, but you can't thrash the presenting one since it's holding and containing ("defining context") the new one.
If you use a navigation controller for your navigation hierarchy (I don't know if you can), you can override the back button and use something like
UIViewController * prev = self.navigationController.viewControllers[self.navigationController.viewControllers.count -2 ]
[self.navigationController popToViewController:prev animated:YES]
With a modal view controller, you may try something like (I haven't tried but it may work)
[self.presentingViewController.navigationController popViewControllerAnimated:YES]
You should write one of these code into the target action of your close button.
iOS doesn't maintain a global stack of controllers in the way that Android does. Each app shows a controller at its root, and that one is responsible for showing the other controllers in the app. Controllers can display other controllers modally using presentViewcontroller:animated:completion: but the presenting controller remains underneath the presented one.
If your current controller is the root controller, then instead of using presentViewcontroller:animated:completion: you'd just do this:
self.view.window.rootViewController = nextViewController;
It's very common for the root controller to be a UINavigationController, which does manage a stack of controllers. If that is the case, and if your current controller is at the top of the stack, you'd do this:
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController pushViewController:nextViewController animated:YES];
If your setup is different, you'd do something different; it's hard to say what without knowing more. But it's most likely that you'd be in the UINavigationController case.
In the viewDidAppear of your nextviewcontroller you could add :
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
NSArray *controllers = self.navigationController.viewControllers;
NSMutableArray *newViewControllers = [NSMutableArray arrayWithArray:controllers];
[newViewControllers removeObjectAtIndex:[controllers count]-2];
self.navigationController.viewControllers = newViewControllers;
}
There is nothing available like this in iOS but you can achieve it doing something like below
NSArray *viewControllers=[self.navigationController viewControllers];
NSMutableArray *newControllers=[[NSMutableArray alloc] init];
for(int i=[viewControllers indexOfObject:self];i<viewControllers.count;i++){
[newControllers addObject:[viewControllers objectAtIndex:i]];
}
[self.navigationController setViewControllers:[[NSArray alloc] initWithArray:newControllers]];
I have tried the method of storing all the view controllers in an array but it didn't work for me . When you try popViewController it will move to the View Controller which is last in the stack.
You can make 2 navigation controllers and switch between them and also switch between the view controllers of a particular Navigation Controller.
For eg.
You can switch between 2 Navigation Controller using the following code:
FirstNavController *fisrtView=[storyboard instantiateViewControllerWithIdentifier:#"firstnavcontroller"];
self.window.rootViewController = firstView;
}else{
SecondNavController *secondView=[storyboard instantiateViewControllerWithIdentifier:#"loginnavcontroller"];
self.window.rootViewController = secondView;
}
If your FirstNavController has 2 ViewControllers then you can switch between them using pushViewController
SecondViewController *sc = [self.storyboard instantiateViewControllerWithIdentifier:#"secondviewcontroller"];
[[self navigationController] pushViewController:sc animated:YES];
and popViewController
[self.navigationController popViewControllerAnimated:YES];

Objective C - navigation button without animation but with option to Perform back

I'm kind new in all the Objective C stuff so try to understand :)
i want to use a navigation button to move to the next view but without any animation.
and i need to save the Current info in the source view and be able to have back button in the destination view.
in modal style i can't save my info and when i'm back to the screen all the info disappeared.
in push style i can use the back button but i cant stop the animation.
in custom style i didn't make it either
help?
btw - please try to give specific answer so i can understand :) THNKS
If you are having navigation controller you can easily do this by pusing viewController to current navigation stack. If you don't want to navigate with an animation you can pass NO to animated value like this.
[self.navigationController] pushViewController:controller animated:NO]; If you want pass YES.
Now when ever you will push view controller you will get a back button, its navigation controller duty to create it for you. Title of this button will be same as source view controller title, if there is no title button title will be back.
Now how you can do that, add a button to your source view controller and assign an action. Call this code in action of that button.
You can add button by interface builder and can set action by clt+drag to source file. Or you can add that button by code.
if you want to do it by code add this in viewDidLoadMethod
UIButton *next = [UIButton alloc] init];
[next setTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
And then add btnClicked method in
- (IBAction)btnClicked:(id)sender{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
Second* controller= (Second*)[storyboard instantiateViewControllerWithIdentifier:#"Second"];
[self.navigationController] pushViewController:controller animated:NO];
}
Edit
It would be better first you go to this link and read some basics.
You can use a UINavigationController to posh/pop all your view controllers. You can control the animation using
[[self navigationController] pushViewController:controller animated:(NO)];
or
[[self navigationController] popViewControllerAnimated:controller animated:(NO)];
I hope that helps. Here is a tutorial on using UINavigationController
http://bharanijayasuri.wordpress.com/2012/12/19/simple-uinavigationcontroller-tutorial-2/

Preserve Scroll Position When Pushing ViewController In Code in a Storyboard App

I have a storyboard app that has a few view controller that need to get pushed on the navigation stack programmatically, instead of with segues. I'm using the following code to do it:
POCollectionViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"categoryView"];
POCategory* destination = (POCategory*)self.collections[indexPath.row];
[vc setShowingCollection:destination];
[self.navigationController pushViewController:vc animated:YES];
My problem is that when I use segues to push view controllers and I press the 'back' button, the scroll position is preserved, but when I use the above code and press the 'back' button, my previous view controller appears with the scroll bar at the top.
Is it re-instantiating a view controller that is supposed to be already on the navigation stack? How can I preserve the scroll position?
EDIT
Code for setShowingCollection:
-(void)setShowingCollection:(POCategory*)collection
{
self->showingCollection = collection;
self.title = collection.name;
self.HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.HUD.delegate = self;
[self.HUD showWhileExecuting:#selector(buildDisplayItems) onTarget:self withObject:nil animated:YES];
}
The buildDisplayItems method fetches a bunch of the data from the server based on the showing collection's ID.
I think that you are not popping the controller correctly, your are not poping to the pushed controller, but popping to a newest controller. How you are doing the pop controller in your back button ?
you should do like this :
[self.navigationController popViewControllerAnimated:YES];
My immediate thought is if you must instantiate a new controller for every "segue" you will have to save the scroll position and when you reload the view cause the the uiscrollview to scroll.
Something like this saved in a property should do the trick:
CGRect scrolledRect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, scrollView.bounds.size.width, scrollView.bounds.size.height);
Then when you reload:
[scrollView scrollRectToVisible:scrolledRect animated:NO];

Jumping between views in Navigation controller

I need to jump between view controllers. For example:
View1: First screen (Just logo)
View2: Download Screen
View3: First app screen (Some Buttons)
View4-View(N): some app screens
When user enters app the app goes to View1->View2 (downloads stuff)->View 3->View4->View5
Then user wish to go to First app screen (View3) he does:
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:NO];
The first time user enters the app it goes: View1->View3 (The download screen no longer needed), and I have different push segue to go to View3 so lets assume the user goes to: View1->View 3->View4->View5, now he wishes to go back to View3, so the function:
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:NO];
Will return him to View4, and this is WRONG. How can I solve it?
Well if you are using storyboards , what you can do is set your uiviewcontrollers' storyboard id and use it for popping and pushing your views.
Lets say your Storyboards name is MainStoryboard.storyboard
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:nil];
SettingsListViewController *settingsVC = [sb instantiateViewControllerWithIdentifier:#"SettingsListViewController"]; // #"SettingsListViewController" is the string you have set in above picture
[self.navigationController popToViewController:settingsVC animated:YES];
Above solution should work for you , but If I were you I would change the structure of my app , you say :
View1: First screen (Just logo)
View2: Download Screen
Since View1 is just logo and View 2 is also a view that you skip, you can remove them from navigation controller and make View3 your navigation controller's root view controller and when you need view1 and view2 present them as Modal View Controllers,
when you are done with them lets say; user successfully loaded the app dismiss logo screen and present Download Screen if download successful then dismiss it.
So your View3 Will be there as root view controller, lets say your at View(n) you want to go to home screen which is View3 all you need to do is call
[self.navigationController popToRootViewControllerAnimated:NO];
When you are on view(n) and want to pop to view(n-1) just use
[self.navigationController popViewControllerAnimated:YES];
good luck,
I always use this, and it will work fine in your case. In fact the following line of code is copied to my "Notes" for quick copy/paste.
Be sure to import your ViewController.h file, if not.
for (UIViewController *viewController in self.navigationController.viewControllers) {
if([viewController isKindOfClass:["your ViewController" class]]) {
[self.navigationController popToViewController:viewController animated:NO];
}
}
In the second sequence your navigation stack changes and view3 would be at index 1. so
[[self.navigationController popToViewController:[array objectAtIndex:1] animated:NO];
would be the right way of doing it.
according to your sitation use directly name of viewController
create instance of your viewController,like this
i supposed here that your viewController name is-view3Controller
View3Controller view3Controller=[[View3Controller alloc]init];
[self.navigationController popToViewController:#"view3Controller" animated:NO]
or if you are using storyboard then
View3Controller view3Controller=[self.storyboard instantiateViewControllerWithIdentifier:#"view3Controller"];
[self.navigationController popToViewController:#"view3Controller" animated:NO]
It sounds like View 2 is not being added to your view controllers array at run time, possibly because of the segue you've created.
Try removing the segue that transitions from View 1 > View 3 and pushing the user past View 2 without animating, as your application's logic requires it:
// If the user needs to skip ahead to view 3, conditionally push view 2 and view 3 without animating
[self.navigationController pushViewController:viewController2 animated:NO];
[self.navigationController pushViewController:viewController3 animated:NO];
Alternatively if you left the segue in place could you not look at the size of the UINavigationController viewControllers property and "guess" based on the size whether or not you skipped View 2? If you did then you can adjust the popToViewController method to pop to the correct index. This is, admittedly less elegant and brittle if you need to skip other views as well.
// Check length of viewController array with 'N' views (pseudo code)
if (self.navigationController.viewControllers.length == N-1)
// View 2 was ignored: pop to objectAtIndex:1
else
// View 2 was included: pop to objectAtIndex:2
If I understood you correctly, your view3 has special view controller, so you can use such code:
NSArray *VCs = [self.navigationController viewControllers];
for (UIViewController *VC in VCs)
{
if ([VC isKindOfClass:[**YOUR-VIEW-CONTROLLER** class]]) {
[self.navigationController popToViewController:VC animated:NO];
}
}
It's simple and it works!
for (UIViewController* controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[<Your View Controller Name> class]]) {
[self.navigationController popToViewController:controller animated:YES];
return;
}
}
Go like this to a particular view controller
[self.navigationController popToViewController:[[self.navigationController viewControllers]objectAtIndex:1] animated:YES];

Resources