Why is the view from my XIB file not being loaded by the UIViewController? - objective-c

In my app delegate, I have:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[CGMContainerViewController alloc] init];
self.window.rootViewController = self.viewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
I have an unmodified CGMContainerViewController.h/m and a modified CGMContainerViewController.xib (added a button). The view is linked to the File Owner.
Why is the view from the XIB not showing?
EDIT: Is it because I'm trying to load a view with a status bar into the window?

From the looks of your code, you aren't loading any XIB files. You need to call initWithNibName:
self.viewController = [[CGMContainerViewController alloc] initWithNibName:
#"CGMContainerViewController" bundle: nil];

Make sure that your File's Owner in the XIB is set to CGMContainerViewController

Okay. I think it was because for a UINavigationController, you have to set the rootViewController and all the layers. I just changed it to a UIViewController because I didn't really need the navigation, just the navigation bar.

The problem which I faced is .If you name your viewController with special character with "-" and some other things your xib will not get loaded
example--> (wrong naming)
view-controller1 (If naming is like this then the xib wont get loaded)
example--->(correct naming)
viewController1 (xib will get loaded)

Related

iOS 7 - Setting the current view controller as root of navigation

I need to set the view controller of the home screen as the the root of the navigation controller, no matter how the user reaches it (push/show or custom segue)
The following code put in the viewDidLoad of a view controller seems to have no effect with iOS 7:
[self.navigationController setViewControllers:#[self]];
The navigation stack does not change at all.
Have you ever experienced any similar issue?
Thanks,
DAN
Call your UIViewController method from app delegate like this..try it out.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController* pp = [[ViewController alloc] init];
UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:pp];
self.window.rootViewController = nav; or [self.window setrootviewcontroller=nav];
[self.window addSubview:[nav view]];
[self.window makeKeyAndVisible];
Only one line to make your current viewController as rootviewcontroller
[[[UIApplication sharedApplication] delegate] window].rootViewController = self;
Create global reference of navigation controller in App Delegate and then with the reference of appDelegate you can change you rootView controller anywhere just type below code :
[appDelegate.navigaitonController initWithRootViewController:viewController];
Note: Here viewController is new viewcontroller reference which you want to set as root of navigation controller .

Objective-c Nested VIewControllers

i would like to create an App whit a structure similar to the native application "Phone" of the iPhone. I will be more precise, the phone application have a tabBar that contains:"Favorites" , "Recents", "Contact", "Keypad" and "Voice Mail".
When we enter in the tab contacts we can see a navigation bar and a tableView.
I would like to have a similar structure but i'm questioning myself about which is the best and most correct way to do it?
I was thinking to start a single view application than use the view controller that is create automatically as a TabbedViewController then i would create another subclass of another viewController and i used it as my NavViewController.
I would have something like
[myTabBar.view addSubview:myNavController];
but how can i set those instance? once i have the automatically created ViewController and i create a SecondviewController how can i set them as the TabViewController and my NavViewController ?
If you're using storyboards, just add a tab bar controller to your storyboard. Then select one of the tab bar's child scenes and then choose "Embed In" - "Navigation Controller" from the Xcode "Editor" menu. If you repeat that process for whichever tabs you want to have navigation controllers. In this screen snapshot, I've added a navigation controller to the first and third tabs, but not the second.
Hopefully this illustrates the idea.
If you're determined to do this with NIBs, the easiest way to get started is create a new project with the Tabbed Application template (and obviously, at the next screen, uncheck "Use Storyboards"):
Then open up the app delegate .m file and replace the default didFinishLaunchingWithOptions that 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;
}
with one that creates a separate navigation controller for each tab for which you want a navigation bar (in this case, I'm adding it to the first one only, but it illustrates the idea):
- (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];
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[navigationController1, viewController2]; // was #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
This a relatively easy way to start a NIB-based tabbed application. You can then customize from there.
Personally, I struggle to imagine why someone would use NIBs rather than storyboards (unless you're trying to support iOS 4), but hopefully this illustrates both techniques.

UINavigationController — left and right flip animation between pushes and pops when presented via presentViewController

Supposed you've got:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view.backgroundColor = [UIColor whiteColor];
[self.window setRootViewController:rootViewController];
[self.window makeKeyAndVisible];
UINavigationController *modal = [[UINavigationController alloc] initWithRootViewController:[[PTFrontViewController alloc] init]];
modal.modalPresentationStyle = UIModalPresentationFormSheet;
[rootViewController presentViewController:modal animated:YES completion:NULL];
return YES;
}
whereas PTFrontViewController and PTBackViewController view controllers have nothing interesting for sake of this example.
How could you push an instance of PTBackViewController from PTFrontViewController animating as in UIViewAnimationTransitionFlipFromLeft or UIViewAnimationTransitionFlipFromRight?
I am already well aware of these three things:
this is not exactly how you should make use of presentViewController
there is a good reason for UINavigationController's default animation
there are several answers how to "customize" UINavigationController's default animation while pushing and poping, but if you try the code for your self you will notice that when a view controller is presented via presentViewController there are drop shadows and background views that won't get animated correctly
So please answer taking these things in mind. Thank you.
First - forget UINavigationController. If you don't need the default animation, just put a UINavigationBar into your controllers. It will get a little easier.
Second - this is a difficult problem, you can't create such an animation only within the modal controller because the background wouldn't be repainted.
Sincerely, the easist solution I see is too forget the modal controller and just add the view controller as a child of your root controller. Then you can control all the animations but you have to write everything by yourself (including the background fading).

How to configure app so that root view controller is found?

I am new and am working on an exercise which involves starting with a navigation-based template. Since I am running Xcode 4.2 which no longer has that template, I have started with an empty application template, and then copied the directory structure of the completed app.
Since the empty app template starts only with an AppDelegate.h, .m files, I started adding other required files, including the MainWindow.xib, and the RootViewController.h, .m files. Did some tweaking of the #import directive so that it could see the right files, and could start alright.
However, when I try to run it on the iOS Simulator, I got this message: Applications are expected to have a root view controller at the end of application launch
Terminating in response to SpringBoard's termination.
Program ended with exit code: 0
What additional changes do I need to make so that the app can see the RootViewController?
Thank you.
In -[AppDelegate application:didFinishLaunchingWithOptions:], you need to set your window's rootViewController property.
You need to set the rootViewController property of AppDelegate's _window:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_window.rootViewController = self.myNavigationController;
[_window makeKeyAndVisible];
return YES;
}
To start a traditional navigation-based project in XCode 4.2, I find it easier to start with the single-view template. Then, in AppDelegate, I substitute the generated UIViewController with a UINavigationController.
self.window.rootViewController=self.yourviewControollerobj
You can set like this. First set the window bounds then add you navigation controller with root view controller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
MainViewController *vc = [MainViewController new];
/*
* If you are using .xib you should create UIViewontroller like this
* MainViewController *vc = [MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil]
*/
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
[self.window setRootViewController:self.nc];
[self.window makeKeyAndVisible];
return YES;
}
MyViewController *rootCtr = [[MyViewController alloc] init];
[rootCtr.view addSubview:myView];
window.rootViewController = rootCtr;

applications expected to have a root view controller console

I am getting a message within the console when I run my app that says:
2011-11-16 19:17:41.292 Juice[8674:707] Applications are expected to have a root view controller at the end of application launch
I have heard from others that this has to do with the method didFinishLaunchingWithOptions
If anyone has any suggestions for why I am getting this error, it would be much appreciated.
My code for the method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
return YES;
}
You should replace the
[window addSubview:tabBarController.view];
to
[self.window setRootViewController:tabBarController];
Maybe you built your project with 'Empty Application' and forgot to set the rootViewController in your didFinishLaunchingWithOptions (which exists in your AppDelegate.m).
However, if you build your project with 'Single View Application' or some other type, the project will set the rootViewController via xib by default (which might be a MainWindow.xib in your project).
I had the same problem on iOS 5, after adding a storyboard to an "empty" project. It turns out I had to remove all the lines in AppDelegate.m that set values to self.window.
- (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];
//[self.window makeKeyAndVisible];
return YES;
}
If you have MainWindow.xib, make sure you set Main Interface in Target's summary to MainWindow.
The way I got this error Applications are expected to have a root view controller at the end of application launch to disappear, was to ensure the loadView method in my root view controller was calling [super loadView]. Hope this helps someone.
Try using self.window instead of window (if your setup has window being synthesized with something like #synthesize window=_window;):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    // Override point for customization after application launch.
    [self.window addSubview:tabBarController.view];
    [self.window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
    return YES;
}
2nd possibility:
In your main.m make sure the last argument is the name of the App Delegate. In your case, it looks like it should be:
retVal = UIApplicationMain(argc, argv, nil, #"JuiceAppDelegate");
Solution:
As #marcus13 said in the comments below.. This was fixed was found in this SO answer: Applications are expected to have a root view controller at the end of application launch - by by moving the UIAlertView methods from -(void)viewDidLoad to -(void)viewDidAppear:(BOOL)animated
Another cause:
I was in IB attaching File Owner to a new small ImageView I'd dragged onto the View. I hadn't called it an IBOutlet in the .h file, so when I ctrl-dragged to it, the new Imageview wasn't listed as a possible connection. The only possibility displayed in the little black box was View. I must have clicked, inadvertently. I made a few changes then ran the program and got the Root Controller error. The fix was reconnecting File Owner to the bottom View in the xib - IB screen.
I just ran into this issue while building a new project from scratch. I added a StoryBoard and build my whole interface, but i did not select a template.
When doing it this way, you have to make sure of 3 main things:
Always select your initial controller (TabBarcontroller or NavigationController) as the initial view in your Storyboard.
Change the code in your Appdelegate.m from this
- (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];
[self.window makeKeyAndVisible];
return YES;
}
to this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
Check your [ProjectName]-Info.plist file. If there is no key named "Main storyboard file base name", you have to manually add it and set it's value to the name of your storyboard file (without the extension).
After i did all of these steps, my application ran perfectly.
I also had the same problem. All I got was a black screen. Turns out I had inadvertently removed:
[self.window makeKeyAndVisible];
from my code. Hope this helps someone!
I had two outlets assigned to "view" in the storyboard's root view controller. Right-click on "view controller" and make sure there's only one "view".
I also had the same error while developing an app that uses sqlite Database.
I was showing alertView when the db file transfer failed.
This was a mistake since you cannot show any popovers/alertview/actions without any rootViewController set!
I fixed it by ensuring that any function that creates and shows these alerts/popovers/actionsheets are called after
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
[someObject functionthatDisplayAlerts];
I know this post is old but I ran into this today.
It's because I created a UIAlertView in didFinishLaunchingWithOptions.
Assuming then we should not be doing this because I commented it out and the error went away. I removed my comments and the error came back.
The app doesn't crash, I just get that logged error.
I had the same problem with my App. It appeared when I added another view controller to my project and tried to set it as the root view controller in AppDelegate. I tried several solutions, but none of them could fix the problem. Finally I found the cause: I had two localized versions of the MainWindow.xib file (One for german and another for english localization). So I deleted the english file and reconnected the IBOutlets in MainView.xib. This solved the problem.
I'm not sure if this will help anybody else, but if you have used interface builder to create your mainWindow and have done all the linking between the delegate make sure you don't have the following code within application:didFinishLaunching ...
[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]
I was having the same error until I removed the above line. Hope that helps!
EDIT: Doing the above now has my viewControllers viewDidAppear method being called twice ?
If you are using Storyboard, but created an empty project, you probably forgot to set the Main storyboard to your *.storyboard file in the Summary tab in your project settings. It helped me to solve this problem.
If you are starting from an empty you have to make this addition to your AppDelegate.m file, to "point" the window to the rootViewController (self.window.rootViewController = [[[ViewControllerName alloc] initWithNibName:#"ViewControllerName" bundle:nil] autorelease];)
Like so:
- (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];
self.window.rootViewController = [[[ViewControllerName alloc] initWithNibName:#"ViewControllerName" bundle:nil] autorelease];
[self.window makeKeyAndVisible];
return YES;
}