How to push Viewcontroller from rootViewController in iOS - ios

I have 2 ViewController. loginViewControl which sets to rootViewControoler :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = loginViewControl;
[self.window makeKeyAndVisible];
return YES;
}
And I create StatusViewController :
*.h
#interface StatusViewController : UIViewController<UITabBarControllerDelegate>
{
IBOutlet UITabBarController *tabBarController;
IBOutlet UIButton *UploadButton;
IBOutlet UIButton *ConvertorButton;
IBOutlet UIButton *CompletedButton;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Now I want to push StatusViewController from loginViewControl(rootviewcontroller).I used below code but it not work.
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]init];
[self.navigationController pushViewController:statusView animated:YES];
[statusView release];
}
Do you have any suggestions? Thanks in advance

You not setting UINavigationViewcontroller at the didFinishLaunchingWithOptions of Window's RootViewcontroller, We can't Push a UIViewController without UINavigationViewcontroller
So First Set LoginViewController as a RootViewController of UINavigationViewcontroller like Bellow:-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[YourLoinViewcontroller alloc] initWithNibName:#"YourLoinViewcontroller" bundle:nil];
UINavigationController *objNavigationController=[[UINavigationController alloc]initWithRootViewController:loginViewControl];
self.window.rootViewController = objNavigationController;
[self.window makeKeyAndVisible];
return YES;
}
EDIT
Connect your StatusViewcontroller's view with File owner like bellow:-
your push method like this:-
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES];
}

Unless your login view controller is a navigation controller, self.navigationController in statusButtonClick will return nil and so this won't work.
Maybe you can try:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:loginViewControl];
[self.window makeKeyAndVisible];
return YES;
}
This will enclose a loginViewController in a navigationController which will permit you to push another viewController in the navigationController's stack.

- (IBAction)statusButtonClick:(id)sender; {
// If used StoryBoard
UIStoryboard *story=[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
StatusViewController *statusView = [story instantiateViewControllerWithIdentifier:#"StatusViewController"];
[self.navigationController pushViewController:statusView animated:YES];
// If used XIB
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES]; }

Related

How to go to UITabBarController after clicking the respective UIButton

how to go on home page on login button click
- (IBAction)loginClick:(id)sender {
HomeVC *secondView = [self.storyboard instantiateViewControllerWithIdentifier:#"home"];
[self.navigationController pushViewController:secondView animated:YES];
self.tabBarController.selectedIndex = 1;
}
First you have to set your login page as a Root controller and when you successfully logged in then you have to change your root controller and make your Tab Bar as a root controller.
Perform this code in your AppDelegate and call these method on your login and logout page.
#property (strong, nonatomic) UIWindow *window;
#property(nonatomic,readonly) UITabBar *tabBar;
#property(nonatomic,strong) UITabBarController *tabBarController;
- (void)Login{
[self.window setRootViewController:nil];
UIStoryboard *MainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle: nil];
UITabBarController *bar= (UITabBarController*)[MainStoryboard instantiateViewControllerWithIdentifier:#"tabbar"];
self.window.rootViewController=bar;
}
-(void)Logout
{
// self.window.rootViewController = nil;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UINavigationController*vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"homepage"];
// Homepage *controller = [[Homepage alloc] initWithDelegate:self];
self.window.rootViewController = vc;
}
Implement didFinishLaunching method this way :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"LoginView"];
BOOL isLogin = [[NSUserDefaults standardUserDefaults] boolForKey:#"IS_LOGIN"];
if (isLogin == YES)
{
rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"MainHomeTabView"];
}
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
And set TRUE when you pressed login button
- (IBAction)login:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:#"IS_LOGIN"];
[[NSUserDefaults standardUserDefaults] synchronize];
TabListViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"MainHomeTabView"];
AppDelegate *appDelagate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelagate.window.rootViewController = vc;
}

Choose which ViewController will display initially

I'm trying to select which ViewController the AppDelegate should display based in a NSUserDefaults BOOL. But the HomeViewController does not display.
I'm using Storyboards and I have my own class of UINavigationController.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
MeuNavigationController *nav = [[MeuNavigationController alloc]init];
if ([NSUD boolForChave:#"firstLogin"]==false) {
ViewController *viewC = [[ViewController alloc]init];
[nav pushViewController:viewC animated:NO];
}else{
HomeViewController *viewP = [[HomeViewController alloc]init];
[nav pushViewController:viewP animated:NO];
}
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
UIViewController *controller = nil;
if ([NSUD boolForChave:#"firstLogin"]==false) {
controller = [[ViewController alloc]init];
}else{
controller = [[HomeViewController alloc]init];
}
self.window.rootViewController = [[MenuNavigationController alloc] initWithRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
You noted that you're doing this off of storyboard. You might want to consider making this change as well:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
// Name of storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *controller = nil;
if ([NSUD boolForChave:#"firstLogin"]==false) {
controller = [[ViewController alloc]init];
// Set this in the storyboard's identity inspector
controller = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
}else{
controller = [storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
}
self.window.rootViewController = [[MenuNavigationController alloc] initWithRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
But you ask... Mr. jakenberg, how does one set their unique view controller identifier?
Cheers

'NSInvalidArgumentException' when adding UINavigation controller

I am trying to add a static UINavigation bar that will be present on a nearly all ViewControllers in my project. The UINavigation bar will have the same 3 buttons throughout (one opens a side menu, one opens a search, one opens a ViewController to allow settings to be changed.
I have followed several tutorials (none are for Xcode5/iOS7) and these haven't worked for me.
Relevant code of "AppDelegate.m":
#import "AppDelegate.h"
#import "MainViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navVC = [[UINavigationController alloc] init];
MainViewController *mainVC = [[MainViewController alloc] init];
[navVC setViewControllers:[NSArray arrayWithObject:mainVC]];
[self.window setRootViewController:navVC];
return YES;
}
Running this gives the following error:
'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
MainViewController.m init
#implementation MainViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
Thanks,
Edit:
To Clarify, I am using a storyboard called 'Main', many ViewControllers with the first one being loaded called 'MainVC' which has a custom class called 'MainViewController'. Thanks to #LML the working code for this is now:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
MainViewController* mainVC = [mainStoryboard instantiateInitialViewController];
UINavigationController *navVC =[[UINavigationController alloc] initWithRootViewController:mainVC];
[self.window setRootViewController:navVC];
[_window makeKeyAndVisible];
return YES;
}
use this because you are using storyboard
-
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:...{
// set to storyboard on launch
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"iPhoneStoryboard"
bundle: nil];
MainViewController* mainVC = [mainStoryboard instantiateInitialViewController];
UINavigationController *navVC =[[UINavigationController alloc] initWithRootViewController:mainVC];
[self.window setRootViewController:navVC];
[window makeKeyAndVisible];
return YES;
}
Use [[UINavigationController alloc] initWithRootViewController:mainVC].
Try this in your didFinishLaunchingWithOptions method-
MainViewController *mainVC = [MainViewController alloc]initWithNibName:#"MainViewController" bundle:nil];
UINavigationController *navVC =[[UINavigationController alloc] initWithRootViewController:mainVC]; // Change here
[navVC setViewControllers:[NSArray arrayWithObject:mainVC]];
[self.window setRootViewController:navVC];
return YES;

Why can't I force landscape orientation when use UINavigationController?

I find many question to force UIViewController to landscape as default:
How to force a UIViewController to Portrait orientation in iOS 6
And try this:
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
But when I use UIViewController inside UINavigationController, I can't force to landscape.Please help!
*Work NOT ok
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[navControl setNavigationBarHidden:YES];
self.window.rootViewController = navControl;
[self.window makeKeyAndVisible];
return YES;
}
*Work OK:
self.window.rootViewController = self.viewController;
Best way to do this is the create extend UINavigationController and write your orientation function inside the extended class.
Class Declaration:
#interface MyNavigationControllerViewController : UINavigationController
#property(nonatomic, assign) UIInterfaceOrientation orientation;
#property(nonatomic, assign) NSUInteger supportedInterfaceOrientatoin;
#end
Implementation of MyNavigationController
#implementation MyNavigationController
#synthesize supportedInterfaceOrientatoin = _supportedInterfaceOrientatoin;
#synthesize orientation = _orientation;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
_supportedInterfaceOrientatoin = UIInterfaceOrientationMaskLandscape;
_orientation = UIInterfaceOrientationLandscapeLeft;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return _supportedInterfaceOrientatoin;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return self.orientation;
}
#end
and use your extended like MyNavigationController as navigation controller to your rootviewcontroller.
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#property (strong, nonatomic) MyNavigationControllerViewController *myNavController;
- (void) reloadAppDelegateRootViewControllerLandscape;
- (void) reloadAppDelegateRootViewController;
#end
So your application delegate didfinishlounchingwithoptions code will be as follow.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.myNavController = [[MyNavigationController alloc] initWithRootViewController:self.viewController];
[self.myNavController setNavigationBarHidden:YES];
self.window.rootViewController = self.myNavController;
[self.window makeKeyAndVisible];
return YES;
}
Only way you can provide different orientation for two different view with same navigation controller isto reload the navigation controller itself. So if you add two methods
- (void) reloadAppDelegateRootViewController{
[[[UIApplication sharedApplication].delegate window] setRootViewController:nil];
[(MyNavigationControllerViewController *)self.myNavController setOrientation:UIInterfaceOrientationPortrait];
[(MyNavigationControllerViewController *)self.myNavController setSupportedInterfaceOrientatoin:UIInterfaceOrientationMaskAll];
[[[UIApplication sharedApplication].delegate window] setRootViewController:self.myNavController];
}
- (void) reloadAppDelegateRootViewControllerLandscape{
[[[UIApplication sharedApplication].delegate window] setRootViewController:nil];
[(MyNavigationControllerViewController *)self.myNavController setOrientation:UIInterfaceOrientationLandscapeLeft];
[(MyNavigationControllerViewController *)self.myNavController setSupportedInterfaceOrientatoin:UIInterfaceOrientationMaskLandscape];
[[[UIApplication sharedApplication].delegate window] setRootViewController:self.myNavController];
}
and call these function after pushing and pop views.
Note:- I don't know whether it is a good way or bad way.
You need to go to your plist file and set the orientations. You can also do this on your project file. The plist orientations settings will override all though.
In your plist you can set both orientation options to landscape button left and landscape button right.

"Applications are expected to have a root view controller at the end of application launch"

My app was launching fine earlier today and now I'm getting this error
"Applications are expected to have a root view controller at the end of application launch"
I've looked at other threads saying to change my code, but I never changed any code to get to this point.
Delegate.h
#interface halo4AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>{
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Delegate.m
#implementation halo4AppDelegate
#synthesize window;
#synthesize tabBarController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
sleep(3);
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[tabBarController release];
[window release];
[super dealloc];
}
#end
The xib for my FirstViewController is titles FirstView.xib , ext
This is not an error, more like a warning.
In your application delegate there is a method named application:didFinishLaunchingWithOptions: in this method you have to make this line before the end of the method self.window.rootViewController = [Some UIViewController]
again, this is not an error, you can ignore the rootViewController IF you have another way to create this rootViewController.
EDIT
This is what your method should looks like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}

Resources