Push View Controller From AppDelegate and Tab Bar - ios

My app is setup with a Tab Bar Controller as the RootViewController, and each Tab has a NavigationController in it. When certain actions are performed, I want the app to push a ViewController onto the screen. The flow of this is that when the app starts, or opens from background, it checks a stored NSDate and compares it to the current date. If the right condition is met, it shows a UIAlertView. If the button I named "Push" is selected, it runs the code to push the new view. This is the reason I need it to be ran from the AppDelegate, as there is no guarantee what tab may be open if the app is being used in the background. Since every tab contains a NavigationController, I thought I could run this from the AppDelegate:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag == 100) {
if (buttonIndex == 0) {
//Cancel
NSLog(#"Cancel");
}
if (buttonIndex == 1) {
NSLog(#"OK");
[self.tabBarController.selectedViewController pushViewController:self.newView animated:YES];
}
}
}
I get a warning message that says UIViewController may not respond to -pushViewController:animated. Any suggestions as to what else I could do?

The return type for selectedViewController is UIViewController, so you need to tell the compiler that it's actually a navigation controller. You do that with a cast,
[(UINavigationController *)self.tabBarController.selectedViewController pushViewController:self.newView animated:YES];

Try this!!
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Cancel");
}else{
NSLog(#"Push");
[self loadTabbar];
}
}
-(void)loadTabbar{
UITabBarController *tabbarController = [[UITabBarController alloc]init];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
ViewControllerOne *tab1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewControllerOne"];
UINavigationController *navi1 = [[UINavigationController alloc]initWithRootViewController:tab1];
tab1.tabBarItem.title = #"Tab1";
tab1.tabBarItem.image = [UIImage imageNamed:#"1.png"];
ViewControllerTwo *tab2 = [storyboard instantiateViewControllerWithIdentifier:#"ViewControllerTwo"];
UINavigationController *navi2 = [[UINavigationController alloc]initWithRootViewController:tab2];
tab2.tabBarItem.title = #"Tab2";
tab2.tabBarItem.image = [UIImage imageNamed:#"2.png"];
NSArray *tabArrays = [[NSArray alloc]initWithObjects:navi1,navi2, nil];
tabbarController.viewControllers = tabArrays;
tabbarController.tabBar.selectionIndicatorImage = [UIImage imageNamed:#"tabbar_selected.png"];
[self.window setRootViewController:tabbarController];
[self.window makeKeyAndVisible];
}
Comment here if this is the one you are looking forward!!

Related

Unable to change tab in UItabbarController, when navigate (Push) to this tabbarController from an another ViewController

Before saying a thing, let me explain my hierarchy. Say, I have an initial navigation controller in which I have my first SignInViewController. From here, I want to go to my UITabbarController, by a button press. Please take have a look into the below image :
My UITabbarController storyboard identifier is this tabbarControllerID. So in my SignInViewController sing-in button action I try like this :
- (void)goToHomeViewController
{
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:mainStoryboard bundle:[NSBundle mainBundle]];
UITabBarController *tabbarController = (UITabBarController *)[storyBoard instantiateViewControllerWithIdentifier:#"tabbarControllerID"];
[self.navigationController pushViewController:tabbarController animated:YES];
}
Which actually bring me to the UITabbarController, but the problem is, I can't change any other tab there. It like freeze. I have tried with tabbarController selected index tabBarController.selectedIndex = 0;. But it's not working. What am I missing here?
Thanks a lot in advance. Have a good day.
PS: I have called - (void)goToHomeViewController like this :
- (void)addUserModelClassToCoreData
{
NSString *givenPhoneNumberWithCountryCode = [NSString stringWithFormat:#"%#%#", self.countryCode, self.phoneNumberTextField.text];
NSString *givenPassword = self.typePasswordTextField.text;
dispatch_async(dispatch_queue_create("myQueue", NULL), ^{
BlockWeakSelf weakSelf = self;
SignInWithPhoneNumberViewController *strongSelf = weakSelf;
UserModelClass *userModelClass = [[UserModelClass alloc] init];
userModelClass = [RetrieveRequestToServerClass retrieveRequestToServerForUserModelForPhoneNumber:[NSString stringWithFormat:#"%#", givenPhoneNumberWithCountryCode]];
if ([userModelClass.user_password isEqualToString:givenPassword]) {
//Add UserModel to CoreData
strongSelf.coreDataManager = [[CoreDataManager alloc] init];
UserModelClass *userModelCls = [[UserModelClass alloc] init];
userModelCls = [strongSelf.coreDataManager retrieveUserModelFromUserModelClassCoreData];
if (userModelCls.user_phone_number.length != 0) {
[strongSelf.coreDataManager deleteFromUserModelClassCoreData];
}
[strongSelf.coreDataManager addToUserModelClassCoreDataForUserModel:userModelClass];
[strongSelf goToHomeViewController];
} else {
ExecuteCodeOnMainThread(
[strongSelf initializeAlertControllerForOneButtonWithTitle:#"Wrong Password" withMessage:#"Your Password is not correct. Please try again." withYesButtonTitle:#"Ok" withYesButtonAction:nil];
)
}
});
}

Set rootViewController inside a class of UINavigationController

I have a UINavigationController in my storyboard and two viewControllers which perform the following function:
InitialViewController: this would be the application's home screen.
FirstTimeViewController: is the screen that appears when the user open
the app for the first time.
My UINavigationController has a class that have the following code:
- (void)viewDidLoad {
[super viewDidLoad];
if ([[ReadPlist initWithPlist:#"Configuration.plist" key:#"initialConfiguration"] boolValue]){
FirstTimeViewController *firstTimeController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"firstTimeView"]; //or the homeController
[self.navigationController pushViewController:firstTimeController animated:NO];
}else{
InitialViewController *initialController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"initialView"]; //or the homeController
[self.navigationController pushViewController:initialController animated:NO];
}
}
Basically this code verify the .plist file if a particular field is active, if YES means that the application is running for the first time, in this case it calls the corresponding viewController.
But this code is not working and I see a NavigationController with a black view. All I would do is the same thing we do in the interface builder, simply drag a line from the UINavigationController inside a UIViewController and set as "Root View Controller", but in my case I'm trying to do this programmatically.
How I can do this?
When you push to FirstTimeViewController Set Bool (User Default) in controller ViewDidload Or in your Success Code.then after set in your AppDelegate below code.
if(Bool value = Yes)
{
FirstTimeViewController *FS=[[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"FirstTimeViewController"];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:FS];
[navController setNavigationBarHidden:YES];
self.window.rootViewController=navController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
}
My answer is
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)options
{
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
FirstTimeViewController *firstTimeVC = [navController.storyboard instantiateViewControllerWithIdentifier:#" FirstTimeViewController"];
InitialViewController *initialVC = [navController.storyboard instantiateViewControllerWithIdentifier:#" InitialViewController"];
if ([[ReadPlist initWithPlist:#"Configuration.plist" key:#"initialConfiguration"] boolValue])
{
// FirstTime
navController.viewControllers = [NSArray arrayWithObject:firstTimeVC];
}
else
{
// Initial
navController.viewControllers = [NSArray arrayWithObject:initialVC];
}
[self.window makeKeyAndVisible];
return YES;
}

how to switch between view inside the uitabbarcontroller in iOS

I am working with UITabBarcontroller, where i want to switch between view s with an UISegmentController, but the UITabBarItem should not be hidden when I click on UISegmentController:
if([sender selectedSegmentIndex] == 0)
{
// UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
// UITabBarController *wc = [mystoryboard instantiateViewControllerWithIdentifier:#""];
// [self.navigationController pushViewController:wc animated:YES];
}
else if([sender selectedSegmentIndex] == 1)
{
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *wc = [mystoryboard instantiateViewControllerWithIdentifier:#"ProfileViewController"];
[self.navigationController pushViewController:wc animated:YES];
}
I will assume that what you are trying to do is have a secondary tab bar (the segment control) to switch between views inside a primary tab. In this case, I would suggest to use a view container, and make the switch inside it. Something like this:
EDIT
You can try this.
But once it changes in The TabBarController,your current VC changes and you cannot access the SegmentedControl as you are in a new VC now, thus you have to again navigate to the older VC via the Tabbar. But you can try this.
if(self.segmentedControl.selectedSegmentIndex == 0){
[self.navigationController.tabBarController setSelectedIndex:1];
}
else {
[self.navigationController.tabBarController setSelectedIndex:0];
}
This code would work when your storyboard is like this

iOS standalone UIViewcontroller , possible?

I'm using AppDelegate method. Why?
When the user click the okay Button, it will force the phone to redirect to a UIControllerView, which is naked to the user eyes.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Daily Vibes"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Wokay"
otherButtonTitles:nil];
[alert show];
}
// Request to reload table view data
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Wokay"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"Vibes"];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:vc animated:YES completion:nil];
}
}
I'm getting error of the following:
Warning: Attempt to present <UIViewController: 0x109721840> on <UINavigationController: 0x10921abe0> whose view is not in the window hierarchy!
Is it possible to accomplish it?
Scenario:
User set time via "DatePicker" then when alarm pop via AppDelegate, when the user click Okay. Then the user will be redirected to a page where a harmony message is displayed via UILabel. But the user has only one button on that page "Back". He has to set another time just to view the message via redirecting.
Example pic:
its because window.rootViewController has type UINavigationController, not UIViewController.
you should initialise a NavigationController.
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:yourUIViewController];
self.window.rootViewController = mainNavigationController;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"Vibes"];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
That's the answer...

Cannot push viewcontroller from appdelegate

In my window base application I need to navigate to editorview from my appdelegate when i click on the second item of my tabbarcontroller it will shows an actionsheet with three option.
actionsheet works fine, it will shows an actionsheet if you choose the second item from tabbar.
But i need to push to the other view when i choose the first option of my action sheet
i declare my actionsheet in appdelegate.
i already implement the actionsheetdelegate
(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
the method is trigerred and it can shows if i do nslog. but it cannot push to the viewcontroller that i want..
here's my code:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
DetailViewController *v2 = [[DetailViewController alloc] init];
NSLog(#"PUSH TRIGER");
[self.window.rootViewController.navigationController pushViewController:v2 animated:YES];
}
}
NOTE: I already embed my tabbarcontroller and navigation controller in my storyboard
It is full of bad answer related to this issue.
I hope mine fits your requirements.
1.- Inside of
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
// 1.- First: instantiate the navigationController. Normally the rootviewcontroller
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
// 2.- Second: Instantiate Storyboard
// It might be tagged MainStoryBoard. Be careful if you've changed it
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
// 3.- Third instantiate the VC you want to navigate
// In my particular case it is called IniciarSliderViewController . Don't forget to import it in the appdelegate. Also pay attention to tagged correctly. In my case MenuSlider
IniciarSliderViewController *controller = (IniciarSliderViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"MenuSlider"];
//4.- And last one, you can now push as you usually do in the VC
[navigationController pushViewController:controller animated:YES];
Don't hesitate to ask if you still have problems
Do like this
What did you assign VC for UITabBarController ? I bet UIViewController? Try assign UINavigationController instead of UIViewController
synthesize UINavigationController *navController;
self.navController = [[UINavigationController alloc] init];
SomeViewController *viewController = [[SomeViewController alloc] initWithNibName:#"SomeViewController" bundle:nil];
self.navController.viewControllers = [NSArray arrayWithObject:viewController];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:
self.navController, nil]];
Then on your actionsheet
[self.navController pushViewController:v2 animated:YES];
EDIT for storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
self.navController = (UINavigationController*) [storyboard instantiateViewControllerWithIdentifier:#"MyNavController"];
Hope that helps
instead of this self.window.rootViewController.navigationController
use UINavigationController object

Resources