appDelegate set rootViewController and viewWillAppear is not called? - ios

this is demo ,I set RootViewController in didFinishLaunchingWithOptions,but viewController's viewWillAppear is not called! I guess it's because the NavigationController added the ViewController that the response chain of the message failed?
I know it should be set to
self.window.rootViewController = navigationController
But I want to know what I set to
self.window.rootViewController = mainViewController
Why not call mainViewController's viewWillAppear? Thank you.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
ViewController *mainViewController = [[ViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.window.rootViewController = mainViewController;
[self.window makeKeyAndVisible];
return YES;
}
viewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSLog(#"viewWillAppear");
}
#end

Hm... interesting.
Keeping the following:
[[UINavigationController alloc] initWithRootViewController:mainViewController];
even though it's not used, seems to be stealing the ViewController's viewDidAppear.
If you comment that line then it works as you want.
i.e:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
ViewController *mainViewController = [[ViewController alloc] init];
//Comment the navigationController instantiation
//UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.window.rootViewController = mainViewController;
[self.window makeKeyAndVisible];
return YES;
}
Maybe the navigationController was set to own the ViewController but since it's not presented on the screen, neither the viewDidLoad nor viewDidAppear occurs until later, but... when you reassign the ViewController to the window, the internal view loading logic feels viewDidAppear is no longer needed to be called.
Maybe a bug or intentional, I don't know.
Note: I don't really have a reason for this behavior. I am just shedding light on what caused it.

Related

How to set Root View Controller programatically in Objective C?

I am a newbie in iOS Development trying to learn how to create and set views programmatically.
i am trying to do swift statement in Obj-C
window?.rootViewController = UINavigationController(rootViewController : ViewController())
Project: Single View Application . Trying to link default Created ViewController.h
As per Krunals Answer i updated code but Navigation Controller is not shown in simulator
Cmd+Click on controller does not navigate to ViewController File
#import "AppDelegate.h"
#import "ViewController.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIScreen *screen=[[UIScreen alloc]init];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.makeKeyAndVisible;
ViewController *controller = [[ViewController alloc] init];
window.rootViewController = [[UINavigationController alloc] initWithRootViewController:controller] ;
Initialise your view controller ViewController before you add (use as root controller of navigation) into navigation controller stack.
Here is sample code to initialise simple view controller
UIViewController *controller = [[UIViewController alloc] init];
Here is sample code to initialise using storyboard
ViewController *controller = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"<ViewController - string identifier of your view controller>"];
Here is sample code to initialise using NIB/Bundle
ViewController *controller = [[ViewController alloc] initWithNibName:#"<ViewController - string NIB name>>" bundle:nil];
According to your code and following comment try this code only (remove other codes from your app delegate launch):
// make sure your NIB name is 'ViewController'
ViewController *controller = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
if (controller != nil) {
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController: controller];
self.window.makeKeyAndVisible;
} else {
//print - your view controller is nil
}
Thanks to Krunal for detailed answer .
Thanks to dan for support
i found issue instead of self.window.rootViewController , i typed window.rootViewController.
setting self.window.rootViewController solved issue.
i dont know difference between self.window.rootViewController and window.rootViewController and reason for issue.
If some one knows answer please provide answer on comment
#import "AppDelegate.h"
#import "ViewController.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIScreen *screen=[[UIScreen alloc]init];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.makeKeyAndVisible;
ViewController *controller = [[ViewController alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:controller] ;
Delele the file Main.storyboard and let the Main interface option empty before you do it.
And add this code:
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
ViewController *vc = [[ViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
UPDATE: If you want to use storyboard with UINavigationController, try this:
Adding UIViewController and adding with UINavigationController
UIStoryboard *storyboard = self.window.rootViewController.storyboard;
UIViewController *rootViewController= [storyboard instantiateViewControllerWithIdentifier:kIdentifier];
[self setRootViewController:rootViewController];
#pragma mark - Set RootView Controller
-(void)setRootViewController:(UIViewController *)rootViewController {
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
UIStoryboard *storyboard = self.window.rootViewController.storyboard;
UIViewController *rootViewController= [storyboard instantiateViewControllerWithIdentifier:kIdentifier];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self setRootViewController:navController];
-(void)setRootViewController:(UINavigationController *)rootViewController {
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}

Modal view does not fire from child controller

My MainViewController loads another view modally.
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *uiViewController = [storyboard instantiateViewControllerWithIdentifier:#"splashViewController"];
[uiViewController setModalPresentationStyle:UIModalPresentationCustom];
[uiViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:uiViewController animated:YES completion:nil];
}
When I load the MainViewController directly from the AppDelegate, the modal view is loaded.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *rootController = [[RootViewController alloc] init];
navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];
[navigationController setNavigationBarHidden:true];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:navigationController];
[self.window makeKeyAndVisible];
return YES;
}
If I load the MainViewController as a child controller of another controller, then the modal view fails to load.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.drawerViewController.leftViewController = self.leftDrawerViewController;
self.drawerViewController.centerViewController = self.mainViewController;
self.drawerViewController.animator = self.drawerAnimator;
UIViewController *rootController = self.drawerViewController;
navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];
[navigationController setNavigationBarHidden:true];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:navigationController];
[self.window makeKeyAndVisible];
return YES;
}
The main view still loads. It's only that the modal view is not created.
What's causing the problem and how can I resolve this?
You should not present another view controller from viewDidLoad method ,
by that time , current view is NOT finished with its view-hieararchy changes ,
You can present new viewcontroller after viewDidAppear is called ,
so you can move that code to viewDidAppear

Programmatically creating UINavigationController in iOS

I am new to iOS. And I want to use navigation controller in my application but I have no any idea how to do it. So can any one guide me step by step for creating navigation in my application.
In appDelegate.h
#property (strong, nonatomic) UINavigationController *navController;
and set the delegate UINavigationControllerDelegate and synthesise object in appDelegate.m
now,
appDelegate.m
you can set navigation controller in didFinishLaunchingWithOptions method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
frstVwCntlr = [[firstViewController alloc] initWithNibName:#"firstViewController" bundle:nil];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.frstVwCntlr];
self.window.rootViewController = self.navController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
In the above code , your firstViewController is set to UINavigationController and UINavigationController added to UIWindow like
self.window.rootViewController = self.navController
Hope this may help you
If you want to create everything programmatically you have to do it in AppDelegate.
But if you don't want to do it programmatically, then just select the ViewController in Storyboard then select menu options:
Editor > Embed In > Navigation Controller
You can creat UINavigationController in Appdelegate and set your first viewcontroller on it.
So for creating a UINavigationController programatically without using storyboards, go to your app delegate and do the following. Create two properties, window and viewController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor=[UIColor clearColor];
self.viewController = [[YourFirstViewController alloc] initWithNibName:#"YourFirstViewController" bundle:nil];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ImageViewController2 *dealVC = (ImageViewController2 *)[storyboard instantiateViewControllerWithIdentifier:#"ImageViewController2"];
[self.navigationController pushViewController:dealVC animated:YES];
where ImageViewController2 is a class name
Here is the code that you should write in app delegate.
UIViewController *vc=[[UIViewController alloc]initWithNibName:#"vc1" bundle:nil];
UIView *view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 568)];
view.backgroundColor=[UIColor redColor];
[vc setView:view];
self.navme=[[UINavigationController alloc]initWithRootViewController:vc];
self.window.rootViewController = self.navme;
For Swift 3.0, using filter:
let desiredController = self.navigationController!.viewControllers.filter { $0 is YourController }.first!
self.navigationController!.popToViewController(desiredController, animated: true)

Can't add NavigationController on TableView using UISplitView

I am having a little hard time here, forgive me if you think my problem is so easy for you.
I am trying to create app using UISplitView. The 1st View on the left is a TableView and the other one on the right is just a normal view.
This is my Code for in AppDelegate.m for UISplitView.
#import "AppDelegate.h"
#import "MasterViewController.h"
#import "DetailViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
MasterViewController *masterVC = [[MasterViewController alloc]init];
DetailViewController *detailVC = [[DetailViewController alloc]init];
UISplitViewController *splitVC = [[UISplitViewController alloc]init];
[splitVC setViewControllers:[NSArray arrayWithObjects:masterVC,detailVC,nil]];
[self.window setRootViewController:splitVC];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Now, I want to add a Navigation Bar on the TableView, I just don't know how to add if I am using SplitView,but I can when I am using a single TableView.
This is my Code in AppDelegate.m using a single View Application that uses TableView. (This is working)
#import "AppDelegate.h"
#import "ViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
//create UINavigationController
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
Hope you can understand what I'm trying to say. I can't post images since i don't have enough reputation. AGAIN.. The question is "How can I add Navigation Controller in my TableView if I used UISplitView?"
Do you think it will be easy for me if I use storyboards instead of using two XIB files?Hope you can help me.
Thanks in advanced!
try this code
in AppDelegate.h file
UINavigationController *detailNavigationController;
UINavigationController *masterNavigationController;
UISplitViewController *HomeSpilitView;
HomeSpilitViewController *HomeMster;
HomeDetailsViewController *HomeDetailsViewControllers;
in AppDelegate.m file
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSMutableArray *array = [NSMutableArray array];
HomeSpilitView = [[[UISplitViewController alloc] init]autorelease];
HomeMster = [[HomeSpilitViewController alloc] initWithNibName:#"HomeSpilitViewController" bundle:nil];
masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:HomeMster] autorelease];
HomeMster.title=#"Title home";
masterNavigationController.navigationBar.tintColor =[UIColor colorWithRed:255/255.0 green:108/255.0 blue:61/255.0 alpha:0.1];
[array addObject:masterNavigationController];
HomeDetailsViewController *HomeDetailsViewControllers = [[HomeDetailsViewController alloc] initWithNibName:#"HomeDetailsViewController" bundle:nil];
detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:HomeDetailsViewControllers] autorelease];
detailNavigationController.navigationBar.tintColor =[UIColor colorWithRed:255/255.0 green:108/255.0 blue:61/255.0 alpha:0.1];
HomeDetailsViewControllers.title=#"details title";
HomeMster.objHomeDetailsViewcontroller=HomeDetailsViewControllers;
HomeSpilitView.delegate = HomeDetailsViewControllers;
[array addObject:detailNavigationController];
[HomeSpilitView setViewControllers:array];
[self.window setRootViewController:HomeSpilitView];
[self.window makeKeyAndVisible];
return YES;
}

AppDelegate and .xib are not implementing properly, but build is successful?

I really don't know how to explain this without pasting all my code, but ill give it a shot. "Assuming" my .hs and .ms are accurate, i have a feeling my .xib is not set correctly, but i cant really paste the code from that. Instead i've zipped the files and uploaded the source code. (if you are brave enough, it's here: http://bit.ly/ZtDkGi ) Im getting a successful build, but my emulator's screen is just black after the app launches.
Essentially, i had to manually add an appDelegate object. i set the class to the appropriate class - but its still not pulling. If someone would be kind enough to help, that would be great.
here's my Test_TableViewAppDelegate.h
#import <UIKit/UIKit.h>
#interface Test_TableViewAppDelegate : NSObject <UIApplicationDelegate>
{
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#end
here's my new Test_TableViewAppDelegate.m
#import "Test_TableViewAppDelegate.h"
#implementation Test_TableViewAppDelegate
#synthesize window=_window;
#synthesize navController=_navController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//self.window.backgroundColor = [UIColor whiteColor];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.backgroundColor = [UIColor greenColor];
self.window = window;
UIViewController *fvc = [[UIViewController alloc] init];
UIViewController *rootController = [[UIViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:rootController];
//UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:fvc];
self.navController = nc;
//[self.window addSubview: nc.view];
//[self.window makeKeyAndVisible];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
return YES;
}
RootViewController.h
#import <UIKit/UIKit.h>
#interface RootViewController : UITableViewController {
NSMutableArray *petsArray;
}
#end
RootViewController.m
#import "RootViewController.h"
#interface RootViewController ()
#end
#implementation RootViewController
and last but not least, main.m ( i think this might be an issue too)
#import "Test_TableViewAppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([Test_TableViewAppDelegate class]));
}
}
thanks in advance. i'd appreciate it :D
in your delegate Test_TableViewAppDelegate
why you adding views two times to the window?
// you could remove these two lines
[self.window addSubview: nc.view];
[self.window makeKeyAndVisible];
//keep these two lines
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
And this view you are adding to the navigationController it is not initalized with any nib name
UIViewController *fvc = [[UIViewController alloc] init];
initialization should be like this instead in your delegate
RootViewController *rootController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:rootController];
I believe the reason that you're getting a black screen is that you are not properly allocating and initializing your navigation controller!
Instead, you should try this code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// create the base window
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.backgroundColor = [UIColor greenColor];
self.window = window;
[window release];
// this is the home page from the user's perspective
FirstViewController *fvc = [[FirstViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:fvc];
self.navigationController = nc;
[fvc release];
[nc release];
// show them
[self.window addSubview: nc.view];
[self.window makeKeyAndVisible];
return YES;
}
Hope this works!

Resources