ios remove tabbar on button touch - objective-c

I've a tab bar based project created and added a login view prior to tab view like this.
AppDelgate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
loginView = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
loginView.delegate = self;
[window addSubview:loginView.view];
[self.window makeKeyAndVisible];
return YES;
}
-(void) loginViewControllerDidFinish:(LoginViewController *) loginViewController{
[window addSubview:tabBarController.view];
}
I'm calling loginViewControllerDidFinish: after authentication in LoginViewController as
[self.delegate loginViewControllerDidFinish:self];
Now in one of the tabs i've added logout button and want to come back to loginView on touch.
-(IBAction) logout:(id)sender{
NMSAppDelegate *appDelegate = (NMSAppDelegate *)[[UIApplication sharedApplication] delegate];
//[appDelegate.tabBarController release];
[appDelegate.tabBarController.view removeFromSuperview];
}
it shows the loginView after calling the above method but after re-login it shows all the previous data and previously selected tab but i want it to be afresh from the first tab.Is there anyway to completely delete the tabbar on logout.so that i'm starting the new session.
Thanks

Cant you create another instance of appDelegate.tabBarController ?
Something like this:
appDelegate.tabBarController = [[UITabBarController alloc] init];
appDelegate.tabBarController.viewControllers = [NSArray arrayWithObject:VIEW_CONTROLLER1, VIEW_CONTROLLER2,nil];
appDelegate.window.rootViewController = tabBarController;
[appDelegate.window makeKeyAndVisible];

Related

UINavigationController is null after going back

I'm having troubles with an UINavigationController which viewControllers property is null after tapping Back on a previously pushed view controller.
The root view controller in AppDelegate is defined with that code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
StartViewController *startVc = [[StartViewController alloc] initWithNibName:#"StartViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:startVc];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
At StartViewController I'm hiding the navigation bar within - (void)viewWillAppear:(BOOL)animated where I've also a UIButton instance where I push the next view controller when tapping with that code:
- (IBAction)buttonTapped:(id)sender {
PhilosophyViewController *philsophyVc = [[PhilosophyViewController alloc] initWithNibName:#"PhilosophyViewController" bundle:nil];
[self.navigationController pushViewController:philsophyVc animated:YES];
}
I'm heading over to the next view as expected. But when tapping the Back button at the navigation bar, the previous view (StartViewController) is empty and when checking the viewControllers property of the navigation controller - it is null?
Any idea?
Thanks in advance.
The back button of the pushed viewController can be hooked up to an IBAction
-(IBAction)backButtonPressed:(id)sender{
[self.navigationController popViewControllerAnimated:YES];
}
This should pop you back to the previous view controller front the stack.
Hope this helps.

Managing navigation controllers / view controllers

Not sure how to title this question, but i'v got such a problem: Up until now i my app runs mainly in one navigationcontroller with table views. But now i'm trying to integrate dropdown settings menu, and can't get it properly done.
The way i'v done now and it works
The changeController is called from one button. ChangeController is in appdelegate.
- (void) ChangeController
{
self.window.backgroundColor = [UIColor blackColor];
DropDownExample *e = [[DropDownExample alloc] initWithStyle:UITableViewStyleGrouped];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:e];
[e release];
[self.window addSubview:self.navigationController.view];
self.window.backgroundColor = [UIColor blackColor];
[self.window makeKeyAndVisible];
}
But this approach has consequances - there is no transition if button is pressed, the settings menu appears instantly, you cannot go back via navigation bar above (nothing there).
So how to do this properly?? I'm new to ios, so just tell me the whole idea how to do this.
Didfinishlaunchingwithoptions method from appdelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease
];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
TableViewController *tableVC = [[TableViewController alloc] initWithNibName:#"TableView" bundle:nil andType:CONTROLLER_TYPE_FIRST];
UINavigationController *navC = [[UINavigationController alloc] initWithRootViewController:tableVC];
self.navigationController = navC;
[tableVC release];
[navC release];
self.window.rootViewController = _navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Ok, here's the answer. Write the method changeController in the same class where the Button exists which calls changeController
In the method, write this.
- (void) ChangeController
{
DropDownExample *e = [[DropDownExample alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:e animated:YES];
[e release];
}
What you want is to insert new UIViewController on the top of the present Stack. If you would be having a navigation Bar at the top by default then there would be a back Btn by default, which would pop up that controller.

How to perform Segue in AppDelegate?

I am trying to complete an application on IOS 5.1 with Storyboard. Basically I am doing a dropbox app. Since I am using Dropbox SDK link to Dropbox is handled in AppDelegate.m. User has the option of be able to unlink from a session and link again in different View Controllers. So every time user link and unlinked app has to switch view from Appdelegate to a view controller that is unconnected to rootviewcontroller
In original Dropbox's example Dropbox handled transition like following code
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
[navigationController pushViewController:rootViewController.photoViewController animated:YES];
}
return YES;
}
return NO;
}
But I am using Storyboard with Navigation Controller and any of the following methods are not working I put methods in comments.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
/*UIViewController *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:#"MeetingViewController"];
[self.navigationController pushViewController:viewController animated:YES]; */
//[self performSegueWithIdentifier:#"xxxx" sender:self];
/* LoginDropboxViewController *loginController=[[LoginDropboxViewController alloc] initWithNibName:#"LoginDropbox" bundle:nil];
[navigationController pushViewController:loginController animated:YES]; */
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
Here is the storyboard of the app
So how can I switch view in AppDelegate.h ?
Note: If I add a segue and name the segue lets say goToMeeting
[self performSegueWithIdentifier:#"goToMeeting" sender:self];
error I get is : No Visible #interface for 'AppDelegate' declares the selector performSegueWithIdentifier:sender
If you consider pushing view manually rather then segueperform following code most probably will work for you
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
//push view manually
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
LoginDropboxViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:#"LoginDropbox"];
[(UINavigationController*)self.window.rootViewController pushViewController:ivc animated:NO];
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
You can do it like this:
UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController;
[[[navigationController viewControllers] objectAtIndex:0] performSegueWithIdentifier:#"goToMeeting" sender:self];
This will only work if the index in viewControllers array matches the one of your view controller and if it exists of course. In this case is the first one (in the array and storyboard).
The segue ("goToMeeting") must not be attached to an action. The way you do this is by control-dragging from the file owner icon at the bottom of the storyboard scene to the destination scene. A popup will appear that will ask for an option in “Manual Segue”; pick “Push” as the type. Tap on the little square and make sure you’re in the Attributes Inspector. Give it an identifier which you will use to refer to it in code.
In my case i need to go to dashboard screen from appdelegate using segue, the code as below in objective c.
if([rememberMe isEqualToString:#"YES"]){
//Goto Dashboard
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SWRevealViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"revealVc"];
self.window.rootViewController = vc;
[self.window.rootViewController performSegueWithIdentifier:#"sw_front" sender:self];
[self.window makeKeyAndVisible];
}else{
//Goto login
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
}
Write inside your didFinishLaunchingWithOptions
Hope it helps some one.

NavigationBar not displaying properling when pushViewController

The problem is pretty simple to understand with pictures.
I have a UINavigationController that allow the user to switch between to views.
The first view contains a search bar and a table view like so :
The second is a basic view where information about the cell are display
When I click on the search bar, the navigation controller gets hidden and the search bar is now at the top.
Now, if I click on a cell, it goes to the second views, but the navigation bar is first hidden like below :
And then, it automatically appears like that :
I have tried a couple of things like show the navigation bar before pushing the next view controller but it is quite ugly..
Does anyone know how to have the show the navigation bar directly on the second view (like in the contact application)?
[UPDATE] : Code
AppDelegate.m (I'm talking about navigationcontroller2)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FirstViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController1.managedObjectContext = [self managedObjectContext];
viewController2.managedObjectContext = [self managedObjectContext];
viewController1.viewController2 = viewController2;
UINavigationController *navigationcontroller1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
[navigationcontroller1.navigationBar setTintColor:[UIColor lightGrayColor]];
UINavigationController *navigationcontroller2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[navigationcontroller2.navigationBar setTintColor:[UIColor lightGrayColor]];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationcontroller1, navigationcontroller2, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
FirstView.m
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!noResultsToDisplay) {
PinDetailsViewController *pinDetailsViewController = [[PinDetailsViewController alloc] initWithNibName:#"PinDetailsViewController" bundle:nil];
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
Pin *pin = (Pin *) managedObject;
[self.navigationItem setTitle:#"Pins"];
[self.navigationController pushViewController:pinDetailsViewController animated:YES];
[pinDetailsViewController updateWithPin:pin];
}
}
If you need anything else, just ask but I think it's all there.
Try to use this code in each viewcontroller.
- (void) viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
Before you push the new view controller, you should unhide the navigation bar:
[self.navigationController setNavigationBarHidden:NO animated:YES];
I had a similar problem with the position of my navbar. Mine was moving up behind the status bar, and I fixed the issue by manually setting the navbar frame:
-(void)adjustNavBarOrigin
{
CGRect r = self.navigationController.navigationBar.frame;
r.origin = CGPointMake(0, 20); // 20 is the height of the status bar
self.navigationController.navigationBar.frame = r;
}
I had to call this method in a number of places, including viewWillAppear: and didRotateFromInterfaceOrientation:, but it worked a treat :)
Hiding the UINavigationBar can disturb the properties sometimes. Try using the property alpha instead of hidden.

UITabBarController with a UIPopOverController with Multiple Views

I am working on a small app, according to the requirement the app should have a tabBarItem with 3 items. For this I have programmatically created the tabBarController in the AppDelegate.m file and added the 3 different viewControllers, instantiated them and everything is working good. I see the tabBarItems and all views are working. In one of the views lets say in SecondViewController I show a popOverController where I used a UITableView and populate it with items. When I click one of the items it should show another view lets say sendFeedback. Until there everything is working fine, but as soon as this sendFeedback is presented as the modal view, it occupies the whole app i.e it hides the tabBarItem.
I present the important pieces of code here for review:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
viewController1.title = #"First";
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController2.title = #"Second";
UITableViewController *tableView3 = [[tableViewController alloc]initWithNibName:#"tableViewController" bundle:nil];
tableView3.title = #"Third";
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, tableView3 ,nil];
self.tabBarController.delegate = self;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
[viewController1 release];
[viewController2 release];
[tableView3 release];
return YES;
}
In my popOverViewController.m file I am checking which row is selected in the table according to that I present the view
#pragma mark - TableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
sendFeedback *sendEmailViewController = [[sendFeedback alloc]initWithNibName:#"sendFeedback" bundle:nil];
downLoad *downloadFilelViewController = [[downLoad alloc]initWithNibName:#"downLoad" bundle:nil];
if (indexPath.row == 0)
[self presentModalViewController:sendEmailViewController animated:YES];
else
[self presentModalViewController:downloadFilelViewController animated:YES];
}
Can anyone guide me how to overcome this with the multiple views. In case if anyone requires more information from my side I would be glad to provide.
NOTE: It is the same with the other view (downLoad) as well
EDIT: Here is how I am initializing my PopOverController in the AppDelegate.m file
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if([viewController isKindOfClass:[SecondViewController class]]){
NSInteger index = [[self tabBarController] selectedIndex];
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
PopOverViewController *popoverView = [PopOverViewController new];
popoverView.contentSizeForViewInPopover = CGSizeMake(250, 85);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverView];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Thanks
Modal view controllers are used to "block" your application and fulfill a task before you can proceed. So modal view controllers are not what you want to use.
Instead wrap your controllers which have to be shown in the popover in a navigation controller. In the tableView:didSelectRowAtIndexPath: method you can push the corresponding view controller to the navigation stack.
To slove your problem:
At the place where you create the popovercontroller initialize it with a new UINavigationController. And the navigation controller you have to initialize with a rootviewcontroller namely PopOverViewController.m.
PopOverController *popoverContentController = [[PopOverController alloc] init];
UINavigationController *navcon = [[UINavigationController alloc] initWithRootViewController:popoverContentController];
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContentController];
And in PopOverController.m
if (indexPath.row == 0)
[self.navigationController pushViewController:sendEmailViewController animated:YES];
else
[self.navigationController pushViewController:downloadFilelViewController animated:YES];