Push View Controller from app delegate in tab bar - ios

Im trying to display a ViewController, from my openURL function inside my AppDelegate class, but im not having any luck. Ive tried every solution i could find on the internet, im not sure what im doing wrong... please note i have a tabbed application..
I dont really want to use self.tabBarController.selectedIndex because I really want to display a custom built controller like so:
CategoryTableViewController *controller = nil;
NSUInteger catId = 6;
NSString *title = #"Cat Title!";
NSManagedObjectContext *inMemoryContext = [xyzclient newContextUsingInMemoryStore:YES];
controller = [[CategoryTableViewController alloc] initWithManagedObjectContext:inMemoryContext];
[(CategoryTableViewController *) controller setParentCategory:catId];
[(CategoryTableViewController *) controller setFilterCategory:NO];
[(CategoryTableViewController *) controller setStopRefresh:YES];
controller.title = title;
[self.tabBarController.selectedViewController.navigationController pushViewController:controller animated:YES];
Here is the code ive written:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSString *scheme = [url scheme];
if ([scheme hasPrefix:#"xyz"]) {
//Attempt 1
UINavigationController *searchNavigationController = [self navigationControllerForViewControllerClass:[SearchTableViewController class]];
[self.tabBarController.selectedViewController.navigationController pushViewController:searchNavigationController animated:YES];
//Attempt 2
NSManagedObjectContext *inMemoryContext = [DealsClient newContextUsingInMemoryStore:YES];
SearchTableViewController *controller = [[SearchTableViewController alloc] initWithManagedObjectContext:inMemoryContext];
[self.tabBarController.selectedViewController.navigationController pushViewController:controller animated:YES];
}
}
- (UINavigationController *)navigationControllerForViewControllerClass:(Class)viewControllerClass {
BaseViewController *viewController = [[viewControllerClass alloc] init];
viewController.context = [self managedObjectContext];
UINib *nib = [UINib nibWithNibName:#"BaseNavigationController" bundle:nil];
UINavigationController *navigationController = [[nib instantiateWithOwner:nil options:nil] lastObject];
navigationController.viewControllers = [NSArray arrayWithObject:viewController];
return navigationController;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[super application:application didFinishLaunchingWithOptions:launchOptions];
self.window.rootViewController = self.tabBarController;
[DClient setBaseManagedObjectContext:[self managedObjectContext]];
UINavigationController *featuredNavigationController = [self navigationControllerForViewControllerClass:[FeaturedTableViewController class]];
featuredNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(#"Home", nil) image:[UIImage imageNamed:#"tabbar_home"] tag:TabBarTabHome];
UINavigationController *browseNavigationController = [self navigationControllerForViewControllerClass:[CategoryTableViewController class]];
browseNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(#"Browse", nil) image:[UIImage imageNamed:#"tabbar_browse"] tag:TabBarTabBrowse];
UINavigationController *searchNavigationController = [self navigationControllerForViewControllerClass:[SearchTableViewController class]];
searchNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(#"Search", nil) image:[UIImage imageNamed:#"tabbar_search"] tag:TabBarTabSearch];
UINavigationController *messagesNavigationController = [self navigationControllerForViewControllerClass:[MessagesTableViewController class]];
messagesNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(#"Messages", nil) image:[UIImage imageNamed:#"tabbar_messages"] tag:TabBarTabMessages];
UINavigationController *cartNavigationController = [self navigationControllerForViewControllerClass:[CartTableViewController class]];
cartNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(#"Cart", nil) image:[UIImage imageNamed:#"tabbar_cart"] tag:TabBarTabCart];
NSArray *viewControllers = [NSArray arrayWithObjects:featuredNavigationController, browseNavigationController, searchNavigationController, messagesNavigationController, cartNavigationController, nil];
[self.tabBarController setViewControllers:viewControllers animated:NO];
[xyzEngine setTabBarController:self.tabBarController];
[self.tabBarController setCartBadgeValue:[xyz numItemsInCart]];
NSLog(#"Loaded the page....");
return YES;
}

Ok I'm still not entirely sure of what you're trying to achieve exactly so I'm gonna assume the following:
You have a tab bar controller with 5 items. Each item is a navigation controller that has a specific class. Based on the url parameter passed to application:openURL:sourceApplication:annotation: you want to select the proper item (which was already been loaded previously in application: didFinishLaunchingWithOptions) of your tab bar controller .
Here's my attempt:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([scheme hasPrefix:#"xyz"]) {
Class navigationControllerClass = [SearchTableViewController class];
NSUInteger navigationControllerIndex = [self.tabBarController.viewControllers indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
BOOL found = [obj isKindOfClass:navigationControllerClass];
if (found) {
*stop = YES;
}
return found;
}];
if (NSNotFound != navigationControllerIndex) {
self.tabBarController.selectedIndex = navigationControllerIndex;
}
}
}
Take 2
In your 2 attempts you're creating a new navigation controller and then try to push it on something that's nil (self.tabBarController.selectedViewController.navigationController is nil since self.tabBarController.selectedViewController is a navigation controller).
Whatever you're pushing in your navigation controller cannot be another navigation controller. So you need to create a simple view controller of type UIViewController and push it to the currently selected navigation controller of your tab bar.
if ([scheme hasPrefix:#"xyz"]) {
MYViewController *controller = [[MYViewController alloc] initWithManagedObjectContext:inMemoryContext];
[(UINavigationController *)self.tabBarController.selectedViewController pushViewController:controller animated:YES];
}

Related

Hide login view if user logged in

i'm try to never show user login view if he logged in
i do this in viewWillAppear
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"userName"]) {
NSDictionary *d = [defaults objectForKey:#"currentUser"];
UserProfile *userData = [[UserProfile alloc]initWithDictionary:d];
[[NetworkModel sharedManager] setCurrentUser:hh];
[self loginResults];
}
self.navigationController.navigationBarHidden = YES;
}
and loginResults function
-(void)childrenReceived:(NSNotification *) notification
{
[SVProgressHUD dismiss];
NSDictionary *userInfo = notification.userInfo;
NSArray *allKids = [userInfo objectForKey:#"children"];
RootViewController *sideBarRoot= [self.storyboard instantiateViewControllerWithIdentifier:#"root"];
sideBarRoot.children = allKids;
[self dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:sideBarRoot animated:YES completion:nil];
}
check the below coding
#interface AppDelegate : UIResponder <UIApplicationDelegate>
-(void) didFinishLogin
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
CCKFNavDrawer*homeNavController = (CCKFNavDrawer*)[mainStoryboard instantiateViewControllerWithIdentifier:#"NavigationLoginID"];
[self.window makeKeyAndVisible];
self.window.rootViewController = homeNavController;
-(void)didFinishLogout
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UINavigationController *homeNavController = (UINavigationController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"LoginNavigationID"];
LoginVC *objloginVC = (LoginVC*)[homeNavController topViewController];
objloginVC.delegate=self;
[self.window makeKeyAndVisible];
self.window.rootViewController = homeNavController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if( [[[NSUserDefaults standardUserDefaults]objectforkey:#"loginKey"]isequaltostring:#""])
[self didFinishLogout];
else
[self didFinishLogin];

How to edit NSMutableArray in other Class

I have NSMutableArray in "AppDelegate.h"
#property (strong, nonatomic) NSMutableArray *myArray;
and "AppDelegate.m"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.myArray = [[NSMutableArray alloc] init];
return YES;
}
In UITableViewController i add objects in NSMutableArray
- (IBAction)AddComment:(UIBarButtonItem *)sender
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
SectionObject *sectionObject = [[SectionObject alloc] init];
sectionObject.id = (NSInteger*)appDelegate.myArray.count;
sectionObject.name = [NSString stringWithFormat:#"New object %i",appDelegate.myArray.count];
[appDelegate.myArray addObject:sectionObject];
[self.tableView reloadData];
}
To edit the object I pass other UITableViewController objects from the array controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UINavigationController *navController = segue.destinationViewController;
ExerciseTableViewController *controller = (ExerciseTableViewController *)navController;
controller.contactdb = [appDelegate.myArray objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
}
When i am going back to write
-(void)viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
self.contactdb.name = self.nameTextField.text;
}
[super viewWillDisappear:animated];
}
I receive an error 'EXC_BAD_ACCESS'. If i not edit self.contactdb.name, I dont have error. How can i edit object in other controller?
Your if-statement:
if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound)
basically guarantees your view controller has already been removed from the navigation stack. That's why you get a EXC_BAD_ACCESS error when trying to access properties from that view controller. You should place your self.contactdb.name = self.nameTextField.text statement somewhere else.

IOS: Load a View Controller When App is Launched from Browser using url schemes?

I am new to iPhone developing , My app is based on video conferencing, I have a task where an app should launch from browser using URL schemes. I have done it but problem is when app launched from browser it should load particular view controller. I am using Storyboard. Here is the code which I tried.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if (!url) { return NO;
}
NSString *URLString = [url absoluteString];
[[NSUserDefaults standardUserDefaults] setObject:URLString forKey:#"url"];
[[NSUserDefaults standardUserDefaults] synchronize];
URLParser *parser = [[URLParser alloc] initWithURLString:URLString];
username = [parser valueForVariable:#"USERNAME"];
NSLog(#"%#", username); //b
sessid = [parser valueForVariable:#"SESSION_ID"];
NSLog(#"%#", sessid); //(null)
tokenid = [parser valueForVariable:#"token"];
NSLog(#"%#", tokenid); //yes
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
ViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"VideoController"];
return YES;
}
This is how I do it..
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
//get parameters
[self goResetPassword:dict];
}
return YES;
}
- (void) goResetPassword:(NSDictionary*) dict{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UINavigationController *root = [[UINavigationController alloc]initWithRootViewController:[storyboard instantiateViewControllerWithIdentifier:#"resetPasswordView"]];
self.window.rootViewController= root;
ResetPasswordViewController *vc = (ResetPasswordViewController*)[[root viewControllers] objectAtIndex:0];
[vc loadData:dict];
}
hope it helps... GL HF
According to your comment your initial ViewController is NavigationController. This is how you can push the required ViewController.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
// same code
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
// Get instance of initial Viewcontroller from storyboard
UINavigationController *navController = [storyboard instantiateInitialViewController
];
// Get instance of desired viewcontroller
ViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"VideoController"];
// Push ViewController on to NavigationController
[navController pushViewController:viewController animated:NO];
return YES;
}
Check It
UIStoryboard *board = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
UINavigationController *nav = [[UINavigationController alloc] init];
[nav setNavigationBarHidden:NO];
IntroVC *initailView = [board instantiateViewControllerWithIdentifier:#"Intro"];
[nav pushViewController:initailView animated:YES];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
UIApplication *sharedApplication = [UIApplication sharedApplication];
[sharedApplication unregisterForRemoteNotifications];

uitabbar item 2 not being set as selected item

I have this code in my app delegate:
- (void) refreshTabBar{
if(mainTabBarController){
UITabBarItem *tab1 = [[UITabBarItem alloc] initWithTitle:#"Page1" image:[UIImage imageNamed:#"1_icon.png"] tag:3];
UITabBarItem *tab2 = [[UITabBarItem alloc] initWithTitle:#"Page2" image:[UIImage imageNamed:#"2_icon.png"] tag:1];
UITabBarItem *tab3 = [[UITabBarItem alloc] initWithTitle:#"Page3" image:[UIImage imageNamed:#"3_icon.png"] tag:2];
UITabBarItem *tab4 = [[UITabBarItem alloc] initWithTitle:#"Page4" image:[UIImage imageNamed:#"4_icon.png"] tag:4];
UITabBarItem *tab5 = [[UITabBarItem alloc] initWithTitle:#"Page5" image:[UIImage imageNamed:#"5.png"] tag:0];
[[[mainTabBarController viewControllers] objectAtIndex:3] setTabBarItem:tab1];
[[[mainTabBarController viewControllers] objectAtIndex:1] setTabBarItem:tab2];
[[[mainTabBarController viewControllers] objectAtIndex:2] setTabBarItem:tab3];
[[[mainTabBarController viewControllers] objectAtIndex:4] setTabBarItem:tab4];
[[[mainTabBarController viewControllers] objectAtIndex:0] setTabBarItem:tab5];
//reload the ClaimViewController
//[[[[[mainTabBarController viewControllers] objectAtIndex:2] childViewControllers] objectAtIndex:0] reloadView];
NSLog(#"setting selected tabbar controller index to 2");
mainTabBarController.selectedIndex = 2;
[mainTabBarController setSelectedIndex:2];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
mainTabBarController = [[UITabBarController alloc] init];
UIViewController *viewController = nil;
viewController = [storyboard instantiateViewControllerWithIdentifier:#"SplashScreenViewController"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
//initialize objects
facebookNetworkController = [[FacebookNetworkController alloc]init];
//UI cutomizations
[self applyTheme];
//TestFlight SDK
[TestFlight takeOff:#"xxxxxxxxxxx-xxxxxxxx-xxxxxxxxx-xxxxxxx"];
// Let the device know we want to receive push notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
// ------ GOOGLE ANALYTICS ------- \\
// Optional: automatically send uncaught exceptions to Google Analytics.
[GAI sharedInstance].trackUncaughtExceptions = YES;
// Optional: set Google Analytics dispatch interval to e.g. 20 seconds.
[GAI sharedInstance].dispatchInterval = 20;
// Optional: set Logger to VERBOSE for debug information.
[[[GAI sharedInstance] logger] setLogLevel:kGAILogLevelNone];
// Initialize tracker.
tracker = [[GAI sharedInstance] trackerWithName:#"YOYOYOYOYOYO" trackingId:#"UA-43403680-1"];
// NEW RELIC
[NewRelicAgent startWithApplicationToken:#"a6a6a6a6a6a6a6a6a6a6as6as6a6a6"];
[self refreshTabBar];
NSLog(#"Application did finish launching");
return YES;
}
For some reason it does not select this index.
What am I doing wrong?
[[mainTabBarController tabBar] setSelectedItem:[[[mainTabBarController tabBar] items] objectAtIndex:2]];
'Directly modifying a tab bar managed by a tab bar controller is not allowed.'
You can use [mainTabBarController setSelectedIndex:2];
Let this work be done by controller of tab bar.

Accessing a UITableView when a UINavigationController gets in the way (in a UISplitViewController)

I have a UISplitViewController that is set up like so:
-(IBAction)makeStory:(id)sender{
NSLog(#"makeStory:");
makeStoryTableViewController = [[MakeStoryTableViewController alloc] initWithNibName:#"MakeStoryTableViewController" bundle:nil];
MakeSentenceTableViewController *detailViewController = [[MakeSentenceTableViewController alloc] initWithNibName:#"MakeSentenceTableViewController" bundle:nil];
UISplitViewController *splitViewController = [[[UISplitViewController alloc] init] autorelease];
UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:makeStoryTableViewController]autorelease];
UINavigationController *detailNav = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, detailNav, nil];
splitViewController.delegate = makeStoryTableViewController;
StoryBotAppDelegate *appDelegate = (StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:splitViewController];
}
When I try to set detailView in the UISplitView delegate as a result of didSelectRowAtIndexPath:, I can only access the NavigationController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"ViewControllers: %#", [self.splitViewController viewControllers]);
MakeSentenceTableViewController *detailViewController = [[self.splitViewController viewControllers] objectAtIndex:1];
Story *storySet = [fetchedResultsController objectAtIndexPath:indexPath];
NSLog(#"detailViewController: %#", detailViewController); //Logs a UINavigationController
[detailViewController setStory:storySet]; //Fails here because Navigation Controllers Can't setStory!
[detailViewController refreshTables];
}
Which makes sense, but how do I access the TableViews that the UINavigationControllers are responsible for? If I remove *rootNav and *detailNav and replace them with the UITableViews in the splitViewController.viewControllers statement it works fine, but then I have no navigation bar:
MakeSentenceTableViewController *detailViewController = [[MakeSentenceTableViewController alloc] initWithNibName:#"MakeSentenceTableViewController" bundle:nil];
UISplitViewController *splitViewController = [[[UISplitViewController alloc] init] autorelease];
//UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:makeStoryTableViewController]autorelease];
//UINavigationController *detailNav = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:makeStoryTableViewController, detailViewController, nil];
splitViewController.delegate = makeStoryTableViewController;
StoryBotAppDelegate *appDelegate = (StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:splitViewController];
How can I access the Detail TableView Controller and keep the Navigation Bar?
Here's how I figured it out. I made two mistakes, and in those mistakes I had to use the UINavigationController.viewControllers ObjectAtIndex: property.
In the function makeStory I was incorrectly assigning a UINavigationController as a delegate instead of a makeStoryTableViewController. I fixed it by doing this, instead (pay special attention to the splitViewController.delegate section):
MakeSentenceTableViewController *detailViewController = [[MakeSentenceTableViewController alloc] initWithNibName:#"MakeSentenceTableViewController" bundle:nil];
UISplitViewController *splitViewController = [[[UISplitViewController alloc] init] autorelease];
UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:makeStoryTableViewController]autorelease];
UINavigationController *detailNav = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, detailNav, nil];
//splitViewController.viewControllers = [NSArray arrayWithObjects:makeStoryTableViewController, detailViewController, nil];
//RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]
splitViewController.delegate = [rootNav.viewControllers objectAtIndex:0];
NSLog(#"delegate: %#", [rootNav.viewControllers objectAtIndex:0]);
StoryBotAppDelegate *appDelegate = (StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"RootViewController: %#", appDelegate.window);
[appDelegate.window setRootViewController:splitViewController];
NSLog(#"AppDelegate.window: %#", appDelegate.window.rootViewController);
I made the same mistake again, this time in the didSelectRowAtIndexPath: and tried to setStory in a UINavigationController. To fix it, I did this (pay special attention to the bit about navControllerDetail.viewControllers:
UINavigationController *navControllerDetail;
navControllerDetail = [[self.splitViewController viewControllers] objectAtIndex:1];
MakeSentenceTableViewController *detailViewController;
detailViewController = [navControllerDetail.viewControllers objectAtIndex:0];
Story *storySet = [fetchedResultsController objectAtIndexPath:indexPath];
NSLog(#"detailViewController: %#", detailViewController);
[detailViewController setStory:storySet];
[detailViewController refreshTables];
Now if only I could figure out how to get the SplitViewController to rotate properly!

Resources