Present ViewController without Back button - iphone

I'm having an annoying problem which takes the best off me :<
I've got 3 view controllers, one to show an advertisement in detail which also has a toolbar. Now what I want is, if the user presses the facebook icon on my toolbar in the first view it has to perform a check. If the check turns out false it needs to go to a 2nd view which shows a login screen. If the user logs in here it has to go to a 3rd screen which shows a simple input + button to update their status.
When the user is at this third screen there should be a button "Back", but this button shouldn't bring them back to View2 but it should bring them back to View1 (the advertisement detail screen).
I figured that I wanted to show the 2nd screen (if check turns false) without pushing it but keeping the NavigationBar + TabBar presented. I added some screenshots to clarify.
First view
Second view
I want this view to be presented without using PushViewController but keep the NavigationBar and TabBar.
Third View
I hope this is enough information, hopefully someone can help me.
Thanks in advance!

Perhaps the most natural thing to do here is to present the login view controller modally. When the user has logged in successfully, the first controller can then push the third view controller onto the navigation stack. This way, the back button will lead directly back to the first view controller, and the user will understand why.

So if we have three UIVIewControllers:
DetailViewController
FacebookLoginViewController
UpdateViewController
We have two viable options:
1) Upon successful login...pop the current LoginViewController and then push the UpdateViewController
PopViewController(detailViewController, false);
PushViewController(updateViewController, true);
2) Present the login Modally and simply present the UpdateViewController
PushModalViewController(loginViewController, true);
//ascertain result of login
if(IsLoggedIn) {
PushViewController(updateViewController, true);
}

consider the following view push logic.
if (!login) {
LoginViewController *lvc = [[[LoginViewController alloc] init] autorelease];
[self.navigationController pushViewController:lvc];
}
else {
ThirdViewController *tvc = [[[ThirdViewController alloc] init] autorelease];
[self.navigationController pushViewController:tvc];
}
It is : create and push the view controller when it is needed.

Try to pop the current view controller (without animation i guess) before pushing the new one. If there is only one view controller in the navigation stack no back button will be shown.
Haven't used Monotouch but i guess something like this:
this.NavigationController.PopViewControllerAnimated(false);
this.NavigationController.PushViewController(newViewController, true);
But as Caleb suggests it's probably better figure out a way that fits the normal navigation behaviours instead of hacking around it.

Related

If "setNavigationBarHidden:YES", then how to come back to previous controller?

I don't want to let the navigation controller show its navigation bar in the whole project.
Now there are three view controllers
(1) Login view controller
(2) Sign up view controller
(3) Home view controller.
I just hope to use action(which can be triggered by any kind of event, i.e. drag gesture, not necessary the pressing button) to switch between these view controllers. But I found once I get to the "signup view controllers", I can not go back to the login view controller, since there is no "BACK" navigation bar.
Questions:
How "PUSH" in one view controller, then "POP" in the other view controller?
Or there is some different way to solve this problem?
Thank you so much, any suggestion is great.
To programmaticaly go backward in a navigation controller's navigation stack, call this method:
[self popViewControllerAnimated:YES];
When and where you call this is up to how you want your app to flow. Essentially, the default navigation controller calls this automatically when the navbar's back button is pressed. But if you hide the navbar and still need to pop back, you can call this method to pop back.
As for pushing forward, it's simply a matter of creating a Push segue on the storyboard, giving it a name, and then in your code, call this method:
[self performSegueWithIdentifier:#"segue_YOUR_SEGUE_ID" sender:self];
On the question of your app, what probably makes most sense is for the login view be a view by itself. It should contain a modal segue to a sign up view for new users as well as a modal segue to the home view controller (which may or may not need to be embedded in a navigation controller).
Performing a modal segue works exactly the same as a push segue (if you're using storyboards. Hook up the segue, choose a modal segue, then call the performSegueWithIdentifier: method in your code when you need the segue to occur.
Dismissing a modal view is slightly different, but still quite simple. It goes like this:
[self dismissViewControllerAnimated:YES completion:nil];
It's fairly check to do with an 'if' statement...
if (self.navigationController.navigationBarHidden == NO) {
//YOUR ACTION
}
Hope that helps!

Pushed ViewController is "greyed out" cannot intact with it

Im relatively new to iOS programming and have been making a recipe based app for the iPad. I've looked around at a lot of answers and can't seem to solve my problem so ill explain how my app is laid out.
Navigation controller -> ViewController -Modal segue -> PreviewViewController -modal segue -> Navigation Controller -> RecipeViewController
Within my RecipeViewController i have a button that when pressed i want it to go back to the "home" screen which for these purposes is the "ViewController".
Here is the code for the button action in "RecipeViewController":
- (IBAction)homeB:(id)sender {
ViewController* viewController = [[ViewController alloc]init];
[self.navigationController pushViewController:viewController animated:YES];
}
However, when i press this button the ViewController is displayed, but the screen is greyed out and i can have no interaction with the screen. I can't post an image of what the screen looks like as i don't have enough reputation yet but i will update it when i can.
I have tried other ways of displaying it such as connecting a segue in the storyboard between the button and the "ViewController" and then activating the segue when the button is pressed. But this messes up other parts of my code as i have to re allocate and initialise the home screen. Would appreciate any help as to why it is coming up with the greyed out screen that cannot be interacted with.
Also just some more notes:
self.navigationController
does not return nil so it is seen, and no errors are displayed when the button is pressed.
Thanks
If you're really doing segues, then I presume this was made in a storyboard. If that's the case, then you should use an unwind segue to get back to ViewController. You do this by adding an IBAction in ViewController that looks like this:
-(IBAction)comingBackFromRecipe:(UIStoryboardSegue*)sender {
NSLog(#"I'm back");
}
The important point is that the sender type be UIStoryboardSegue. Then in IB, in the RecipeViewController, you control drag from your button to the green "Exit" icon at the bottom of the controller. When you let go, you should see the method that you wrote in ViewController -- connect it to that. This will get you back to the same instance of ViewController that you started with.
It's hard to tell without seeing a screenshot, but from what i understand, if you want to go back to the home screen, you shouldn't be pushing a new view controller (unless you really want to add it to the stack?)
To go back to the "home" screen, you should try this:
[self.navigationController popToViewController:viewController animated:YES];
or if your home screen is the root, simply use this:
[self.navigationController popToRootViewControllerAnimated:YES];
Thanks for the responses everyone, i figured out my problem though. My structure was wrong and i realised that i didn't need to have another navigation controller for the Recipe view Controller as i wasn't pushing anywhere from there. So incase anyone else has a similar problem my structure is now as follows:
Navigation Controller -> View Controller -Modal Segue -> PreviewViewController - ModalSegue -> RecipeViewController
I removed the Navigation controller between PreviewViewController and RecipeViewController. This means that they are all modal view controllers. So to get back from the RecipeViewController to the home screen which is "ViewController" i just needed to dismiss the hierarchy of modal views with the following code:
UIViewController * parent = self.presentingViewController;
[parent.presentingViewController dismissViewControllerAnimated:YES completion:nil];
I went back two stages so that both the PreviewViewController and the RecipeViewController where dismissed.
Works great now, thanks for the help anyway everyone.

iOS 5 return to initial nib view resembling a sign out button

this if my first post so please be gentle.
I have an iOS 5 app (using storyboards) where I want the user to have the ability to sign out, and with that reset all settings in the app, and also return the user to the very first nib view.
I have already used this code:
[self.navigationController popViewControllerAnimated:YES];
and the problem with this is that it only sends the user back 1 view and not several.
The issue with this is that I have multiple table views that derive from each other and I want the Sign Out button to remain visible in every single one of these detailed views.
Also, this has to work on both iPhone and iPad (Universal)
Any suggestions?
Thanx.
Why not assign a BOOL value YES on button click, then in the viewWillAppear of each viewController:
(assuming BOOL signingOut)
if(signingOut){ [self.navigationController popViewControllerAnimated:YES]; }
Otherwise, just use:
[self.navigationController popToRootViewControllerAnimated:NO];
Why not set the viewControllers array on the navigation controller.
Or send your logout command to the root controller of the navigation controller and have it pop the navigation controller without animation until there are two left. Then pop the second to last one animated. Then you should still get the navigation animation

problem with tab bar, not displaying the tab bar upon navigating to that page

In my test project I have some 5 tabs on click of a tab it will go to that corresponding class, on click of back in that screen I will come back to my home page but with out the tab bar.. earlier what 5 tabs were there those are not coming ...
following code I am using under back button
where DataEntry is the class to where i need to navigate
- (void) back_Clicked:(id)sender
{
DataEntry *avController;
UINavigationController *addNavigationController;
if(avController == nil)
avController = [[DataEntry alloc] initWithTabBar];
if(addNavigationController == nil)
addNavigationController = [[UINavigationController alloc] initWithRootViewController:avController];
[self. navigationController presentModalViewController:addNavigationController animated:YES];
}
is I have to add that navigation controller to the tab view? how can I get the tab bar on click of back can any one help me ,thanx in advance
As I understand this, you must already be pushing this view controller either via navigation controller or modally. So the idea would be to simply dismiss it right?
If you have used [self.navigationController pushViewController:animated:] then just do [self.navigationController popViewControllerAnimated:YES]; . This should take you back to the earlier view controller.
If you have presented this modally like you have done here, you should do [self.navigationController dismissModalViewControllerAnimated:YES];.
If you need to return back from a view to the previous view using a back button inside a tab view , i would recommend using a navigation controller inside the view for each tab where you require this functionality. Trying to implement a custom back button without using the navigation controller, in my opinion, is only making things tough for yourself.
If you only want one view to be displayed when you tap on a tab bar button then an ordinary view controller inside the tab bar view should suffice.
The tab bar shouldnt be disappearing altogether unless its been implemented incorrectly.

Keep new view in a tab when switching to another tab

This is the situation:
I have a tab bar with 2 tabs. Tab01 and Tab02.
In Tab01 I have a button which pushes repVC:
repVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:repVC animated:YES];
[(UIViewController *)[tabController.viewControllers objectAtIndex:0] setView:repVC.view];
[repVC release];
Inside repVC I have another button which pushes an MFMailComposerViewController:
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
[self presentModalViewController:mail animated:YES];
[mail release];
The problem is: when mailView is shown(in Tab01) and I click Tab02, then back to Tab01, the mailView is hidden and even if I click the email button again, the view won't be presented.
So what I have is: Tab01.view -> repVC.view -> mail.view
For repVC, I use this line when I push the view so that even if I go switch tabs, that view will still be activated:
[(UIViewController *)[tabController.viewControllers objectAtIndex:0] setView:repVC.view];
But I can't do the same for mail because tabController is declared in another class which I cannot import. So I can't access the tabController and set the view for Tab01.
Hope the edit helped the understanding.
Hmm,
I still would suggest to use a Navigationcontroller. Would make things way easier, is conform to apple guidelines and suggestions and is pretty fast implemented. (Just create a Navigationcontroller, put the View of Tab1 as main view and hand it over to the TabbarController. Then for the mailView use [self.navigationController pushViewController:mail animated:YES]; Then the navcontroller "saves" the present view for you when u switch tabs)
But if for some Reason you have to use a modalViewcontroller you could either just deactivate the tabbar while the ModalView is shown or try to implement a switch or a simple if...else case in your ViewWillAppear where u check what screen to load.
Then Clean out the Window and load the right screen.
Hope you get the idea of what I mean, sometimes my way of writing seems to confuse people. ^^
A little more information would be great.
How did u set up your TabbarController?
How do u push the new view? Within a UINavigationController? If not, then do it with a navController, he should save the actual state of view and your problem should be solved.
If u already use a navController please post your ViewDidLoad and ViewWillAppear of the Viewcontroller of Tab 1
As #Amandir points out you could probably solve your problems by using a UINavigationController. I get a feeling that you are trying to abuse the modal view controller concept a bit and that's why it doesn't work as you expect. When you use presentModalViewController:animated: the intention should be that you are displaying a view that is modal, i.e. the user must interact and dismiss the modal view before she can continue.
What the paragraph above means that when you present a modal view controller it shouldn't be possible to use the tab bar. Since you are using the word push I'm guessing that you would like change the view of Tab01 while still being able to use the functionality of the tab bar. The problem is that there isn't any built-in method of pushing view controllers besides UINavigationController. persentModalViewController:animated: should only be used in case where you want a modal view, which on the iPhone means a full screen view.
The easiest way would probably be to use an UINavigationController and hide the navigation bar. Then you would get the functionality I think you are after. The other option is to manually add and remove sub views.
[self.view addSubview:repVC.view];
and
[repVC.view removeFromSuperview];
[self.view addSubview:mail.view];
You can use block animations if you want some fancy transitions.