Dismissing a navigation view controller - ios

I am currently working on a game for the iOS platform. The game's initial view controller is a login screen, and once the player logs in, he gets to a loading screen, and then a navigation view controller containing a table view with a list of current games. The storyboard's relevant view relations look like this:
[login screen] --modalsegue-> [loading screen] --modalsegue-> [navigation controller] --relationship-> [tableview (with logout button)]
I want to make a logout button at the bottom bar of the navigation view's [table view], which takes the player back to the [login screen]. How can I do this?
Thanks in advance!

You can dismiss, self.presentingViewController.presentingViewController or you can use dismissToRootViewController.

[self.navigationController dismissViewControllerAnimated:YES completion:nil];

- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *btnLogout = [[UIBarButtonItem alloc]initWithTitle:#"Logout" style:UIBarButtonItemStyleBordered target:self action:#selector(btnOnClick:)];
self.navigationItem.rightBarButtonItem = btnLogout;
}
-(void)btnOnClick:(id)sender
{
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];
}
I hope...This may help you...

Related

How to create a second splash screen (after default splash screen in ios)?

I tried to add a second splash screen to iOS existing project, this project was too old and using xib's.
So i was planning to show default splash screen first and then my own one image as splash screen after that login page.
This is what i have done so far
In my ViewController.m file i have created on UIView and added one UIImageView its working but the problem is i can see navigationbar also along with second splash screen .
I dont want that navigation bar.
Please help me
Code
ViewController.m in ViewDidload ()
self.navigationController.navigationBar.hidden=YES;
_splash.frame=CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);
_splashImg.frame=_splash.frame;
[self.view insertSubview:_splash aboveSubview:_loginView];
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:#selector(runMethod) userInfo:nil repeats:NO];
[self.view addSubview:_splashView];
[self.view bringSubviewToFront:_splashView];
UIImageView *img=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"rss2.png"]];
img.frame=_splashView.frame;
[_splashView addSubview:img];
Apple allows only one splash screen per project. You can show your custom image as a splash by creating a new view controller. Say SplashViewController. Add an imageView on SplashViewController's view and set your splash image.
Load SplashViewController when you want to show your custom splash.
In SplashViewController's ViewDidLoad:
- (void)viewDidLoad{
[[self navigationController] setNavigationBarHidden:YES animated:YES];
[self performSelector:#selector(loadingNextView)
withObject:nil afterDelay:3.0f];
}
method to load next view
- (void)loadingNextView{
// write code for pushing VC.
}
In your next view controller's ViewDidLoad show navigation bar
[[self navigationController] setNavigationBarHidden:YES animated:YES];
try this
To hide the navigation bar:
[[self navigationController] setNavigationBarHidden:YES animated:YES];
To show it:
[[self navigationController] setNavigationBarHidden:NO animated:YES];
else
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES]; //it hides
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO]; // it shows
}
There's currently no 'official' way to have a second splash screen, so what you're doing is the way to go. The only suggestion I have for you is to add your custom splash screen view to a window instead of the view controller's view. Adding it to the window (and sizing it accordingly) will make your custom view stand above everything else. You might even create a new window and place it at the UIStatusBar level for a similar, cleaner, effect.
Edit: adding sample code
For the simplest solution
UIWindow *window = [UIApplication sharedApplication].delegate.window;
_splash.frame = window.bounds;
[window addSubview:_splash];
...
// later, when you're done
[_splash removeFromSuperview];
For the slightly more complex, but more elegant, solution of creating a new window, please read the UIWindow documentation.
In the AppDelegate You set the navigation controller as a root view controller in that replace with you just do create the UIViewController as a root viewcontroller.
After few second you just do as a performSelector thru change the root view controller to navigation controller and your problem has been resolve.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
SplashScreenController *viewCon=[[SplashScreenController alloc]
initWithNibName:#"SplashScreenController"
bundle:nil];
self.window.rootViewController= viewCon;
[self.window makeKeyAndVisible];
[self performSelector:#selector(loadNavigationController)
withObject:nil afterDelay:0.2f];
}
-(void)loadNavigationController{
HomeController *viewCon=[[HomeController alloc]
initWithNibName:#"HomeController"
bundle:nil];
self.nav=[[UINavigationController alloc]initWithRootViewController:viewCon];
self.window.rootViewController= self.nav;
}
May this help to ease to solve your problem.

Nav Bar Item in XIB that Presents a StoryBoard Tab Bar Root View Controller Segue

My App has a lot going on with it, lol. On my Main Menu, if you click "Chat", it will take you to the Chat XIB.
If you look to the top left in the Navigation Bar I have something called "Main Menu". I want this to take me back to the Main Menu. My Main Menu is on the main.Storyboard. The Chat is an XIB. Both Views have Tab Bars. I've been going in circles all day trying to figure this out. This is the last thing I have tried which crashes:
-(void)MainMenu
{
MainMenuTabBarControllerViewController *MMTBC = [[MainMenuTabBarControllerViewController alloc]init];
[self.navigationController popToViewController:MMTBC animated:YES];
}
- (void)viewDidLoad
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
[super viewDidLoad];
self.title = #"Group";
//---------------------------------------------------------------------------------------------------------------------------------------------
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"New" style:UIBarButtonItemStylePlain target:self
action:#selector(actionNew)];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Main Menu" style:UIBarButtonItemStyleBordered target:self action:#selector(MainMenu)];
//---------------------------------------------------------------------------------------------------------------------------------------------
self.tableView.tableFooterView = [[UIView alloc] init];
//---------------------------------------------------------------------------------------------------------------------------------------------
chatrooms = [[NSMutableArray alloc] init];
}
Since you have two tab bar controllers in your application. I don't think it is a good idea to use navigation controller (push/pop) to manage the transition between them. Try with presentViewController.
When the chat button is pressed, show the second tab view controller.
- (IBAction)chatButtonPressed:(id)sender {
ChatTabBarController *chatTabView = ... // allocate memory and initialize
[self presentViewController:chatTabView animated:YES completion:nil];
}
When the main menu button is pressed, dismiss it.
- (IBAction)mainMenuButtonPressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
Edit:
Just notice a very similar question being asked a couple of years ago. Take a look at this one:
How can I push tab bar controller after click a button from a view in objective c?
You should use storyboards. Try deleting your XIB and start using an Unwind segue on your storyboard. Are you using push or modal? It changes everything. After you migrate to storyboards, read Apple's docs on Unwind segues.
Best regards,

xCode Navigation Back Button not popping detailview

Whenever I press on the 'go back' button on my final detail view, it wont go back to the table view.
I have a storyboard setup like this:
UITabViewController -> UINavigationController -> UITableView -> UINavigationController -> UIView (The detailview).
When I run my program I see the back button, but clicking it does nothing.
Here is the code for DetailViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *backbtn = [[UIBarButtonItem alloc] initWithTitle:#"Go Back" style:UIBarButtonItemStylePlain target:self action:#selector(gobackBtn)];
[self.navigationItem setLeftBarButtonItem:backbtn];
[self configureView];
}
- (void)gobackBtn
{
[self.navigationController popViewControllerAnimated:YES];
}
As if [self.navigationController popViewControllerAnimated:YES]; does nothing.
I'm out of ideas. Why does the backbutton not 'pop' the detailview?
Your detail view controller is the root view controller of the navigation controller. So 'popping' does nothing. You need instead to dismiss the navigation controller. Technically, you should use a delegate to tell your TableViewController to dismiss it, but I think
[self.navigationController dismissViewControllerAnimated:YES completion:NULL];
from within your goBackButton method of your detail view controller will do the trick.

Push to ViewController without back button

I am developing an iOS app which contains login/authentication functionality - basically first time a user logins, in they need to enter relevant login details - then they are passed to main app screens - subsequent visits to the app they will be automatically authenticated.
All above works fine - the issue I have is with the Navigation bar - it appears in the main screen in the main part of the app with a back button - I don't want this to be displayed as they should not be able to return to the login screen once authenticated. I guess it's using the root navigation controller which explains the logic, but is there a way to ignore the navigation controller of the login section so the back button is not displayed in the main app.
Below is a screenshot of the structure to help my explanation - left hand group of screens are the login process right hand is the main app structure.
The code used to switch screens is as follows -
SWRevealViewController *swRevealController = (SWRevealViewController *)navVC;
swRevealController.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:controller animated:YES];
Don't push view controller. Create new hierarchy with:
Objective-C
[self.navigationController setViewControllers:#[controller] animated:YES];
Swift
navigationController.setViewControllers([controller], animated:true)
In the Screen which implements after login, the ViewDidLoad method add the line to hide back bar button.
self.navigationItem.hidesBackButton = YES;
Additionally you can add an 'Logout' option as
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStyleBordered
target:self
action:#selector(LogoutClick)];
self.navigationItem.leftBarButtonItem = backBarButton;
-(void)LogoutClick {
[self showLogoutAlert];
}
-(void)showLogoutAlert {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Do you want to Logout ?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Logout", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[self.navigationController popToRootViewControllerAnimated:YES];
}
}
Use a modal view controller for the login screen so its not part of your navigation controller hierarchy within your navigation root probably in view did load - sample code below:
- (void) viewDidLoad {
......
LoginVC *loginViewController = [LoginVC alloc] init];
loginViewController.parent = self;
[self presentViewController: loginViewController animated:YES completion:NULL];
return;
}
You may or may not dismiss the modal view from the root - if you do, you will need to be able to call the dismiss routine from loginViewController but there are other ways as well and you can put the dismiss inside the modal view (loginViewController)
(void) login_exit:(BOOL)success {
[self dismissViewControllerAnimated:YES completion:NULL];
if !(success) {
.... send message (UIAlertview and ask if he or she wants to try again)
}
else {
}
return;}
Very simple.. Just navigate to rootviewcontroller
SWRevealViewController *swRevealController = (SWRevealViewController *)navVC;
swRevealController.managedObjectContext = self.managedObjectContext;
//-- I think above lines not needed as per your question
[self.navigationController popToRootViewControllerAnimated:YES];
You need to hide the Navigation Bar in the ViewController before you push the SWRevealViewController by using the below line in viewDidLoad
Objective C
self.navigationController.navigationBarHidden = true;
Swift
self.navigationController?.navigationBarHidden = true;
It will not show the back button in the next view controller pushed
2022 answer
#IBAction func SomeScreen() {
let s = UIStoryboard ...
navigationController?.isNavigationBarHidden = true;
navigationController?.pushViewController(s, animated: true)
}
It's that easy.
Write this in viewDidLoad method
self.navigationItem.hidesBackButton = YES;
This will hide the back button for the first view.
ClassA* controller = [storyboard instantiateViewControllerWithIdentifier:#"ClassAIdentifier"];
if (controller != nil) {
[self.navigationController pushViewController:controller animated:YES];
[controller.navigationItem setHidesBackButton:YES animated:NO];
}
You MUST hide the navigationItem after push, otherwise it will be nil.

pushViewController followed by 'back' button sometimes doesn't pop view

I am using pushViewController to push a view in my application. Pressing the back button works about 95% of the time like you would expect. But if I go in and out of the view as fast as possible I run into a condition where the top bar moves as if a pop has occurred, but the view says. In this state, I am left with a back button, (in normal operation I have changed the text of this button to 'cancel'). pressing back will animate the top bar again, and then I am left with no buttons in the top bar, and I'm stuck inside the view.
Do you have any idea what might be going on here? Here are some more details:
The sub view calls these once or twice:
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
also the sub view is extending a BaseViewController. Inside this base controller all of the view methods are overloaded (they just call super). The one that might be interesting is:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self customizeNavigationBar];
}
- (void)customizeNavigationBar
{
[self.navigationController.navigationBar setTintColor:UIColorFromRGB(kNavigationBackgroundColor)];
UIBarButtonItem *backButton_ = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"ID_BUTTON_BACK", #"") style:UIBarButtonItemStyleBordered target:self action:nil];
self.navigationItem.backBarButtonItem = backButton_;
[backButton_ release];
}
Please let me know if you need more code or if I can explain things better.
--- Edit ----
I also am calling Google Analytics in view will appear. I remember this causing other issues in my app:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSError *error;
if (![[GANTracker sharedTracker] trackPageview:#"/app_new_page"
withError:&error]) { }
}
This code is being put in my actual view (not BaseViewController).
I found the problem. The issue was that I was calling setNavigationBarHidden:NO with animated:NO in viewDidLoad to show the nav bar without animation, but using pushViewContoller with animated:YES.
----- originally -----
[self.navigationController pushViewController:controller animated:YES];
and
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
The solution was to remove setNavigationBarHidden from viewDidLoad and move it into viewWillAppear, and to animate it the same way the view was animated. Since my nav bar was appearing instantly, it was possible to press back before the view controller had finished animating (pushing onto the stack), causing all these issues.
----- solution -----
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
Thanks for your help guys!

Resources