I'm trying to make an iPhone app here, and I've gotten it down to a simple HelloWorld problem. For some reason, the following does not work in XCode 4.4. I'd really appreciate figuring out what's going on.
I follow these steps:
Start an 'empty project' type
Name it
Add in a new objective-c class with a .xib. Say this new view controller is StartViewController, so I now have StartViewController .xib, .h, and .m.
Check: file's owner for the .xib matches the .h file. It does in IB.
Change the background of the .xib to something other than black (I like stripes).
Add these lines to the main app delegate:
import "StartViewController.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
StartViewController* theController = [[StartViewController alloc]init];
[self.window addSubview:theController.view];
[self.window makeKeyAndVisible];
return YES;
}
And the app immediately crashes on running with:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "StartView" nib but the view outlet was not set.'
How can I make it work?
EDIT: PS, I have no idea why the code formatting appears to have failed. I was under the impression that it was just four spaces at the beginning of a line...
Do what am error tells you to do. Set an outlet for Startview in your VC.
I'm answering this because it's so ludicrous.
Turns out that order matters.
I deleted the old controlling files, and then added 'startingviewcontroller', edited the appdelegate function to be startingviewcontroller, then it all works. Not sure why that should matter, but hey.
Related
I have received a project from a client that I need to compile, but when I run it gives error Application windows are expected to have a root view controller at the end of application launch and EXC_BAD_Access (code=2, address=0x0)
as far as I know this is due to application:didFinishLaunchWithOptions: in the AppDelegate, but the problem with my project is that there is no AppDelegate file.
EDIT:
I tried to run the project on Xcode 4.5.1 now it is giving the error address doesn't contain a section that points to a section in a object file.
The problem is that there is no AppDelegate file. That is usually where the root view controller is set
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
// set root view controller
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
I also experienced the "Application windows are expected to have a root view controller" error message.
If you are using a storyboard and you have verified:
The app delegate application:didFinishLaunchingWithOptions method is
returning TRUE and doing nothing else.
The view controller is set in IB to be the initial view controller.
The storyboard is appropriately set on the TARGETS Summary tab.
Verify that you have not created a "view" UIView #property and #synthezised it in the view controller implementation. I experienced this and through a lengthy process of elimination had my DOH moment when I realized I had created a "view" UIView property named exactly like the one IB had created and linked to the view controller.
Hope this helps.
I'm wondering if someone could explain (or point me in the right direction)
where the code for instantiating UIWindow disappears to when NOT using storyboards? In the empty-application project template the window is created in application didFinishLaunnching... in your AppDelegate.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
However if using storyboards, the above code is omitted, though obviously UIApplication knows which window to start off with.
Where the application looks for the info.plist file to know which storyboard(s) to start off with.
I'm certain this is all well documented somewhere I just haven't found it. Read this Where is the UIWindow instantiated in an iPhone app? but not much help. I've been at iOS for awhile, just never had to mess with the initial startup of an app until now. Thanks
I think you meant 'where the code disappears to when you are using storyboards.'
The application loads the storyboard according to the "Main storyboard file base name" (UIMainStoryboardFile) key in your Info.plist, and from that storyboard it loads the view controller with the "Is initial view controller" toggle set.
Edit: As asked in the comments, the following code (similar to the initial loading in xib-based apps) will allow you to load and display a storyboard by name upon application launch:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"StoryboardName" bundle:nil];
UIViewController *viewController = [storyboard instantiateInitialViewController];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
}
While using storyboards, the storyboard to be loaded comes from your app's Info.plist file.
There will be a section in your Info.plist file with the key value pair like this:
<key>UIMainStoryboardFile</key>
<string>MainStoryboard</string>
In this case, MainStoryboard is the name of the default storyboard that is loaded.
I have an universal application that had all views in the same file MainWindow.xib. Today I decided to separate these views into their respective xib files (to have MainMenuController.h, MainMenuController.m and MainMenuController.xib for example). Now I can't receive and IBActions. Here is what I did step by step:
I created a new .xib file named MainMenuController.xib and set it's File's Owner to the already existing MainMenuController class.
I copied the view corresponding to the MainMenuController from the MainWindow.xib file and pasted it into the newly created MainMenuController.xib. I set the File's Owner's view to be the newly pasted view (connected in IB).
In the info.plist, I removed the entries for the "Main xib file base name", so the app doesn't open with MainWindow.xib automatically.
I modified the app delegate to create the window programatically and add the MainMenuController to it with this code:
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
mainMenuController = [[MainMenuController alloc] init];
self.window.rootViewController = mainMenuController;
[self.window makeKeyAndVisible];
[mainMenuController release];
"mainMenuController" and "window" are instance variables and also declared as properties.
I have only one AppDelegate class and main.m contains:
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}}
Now when the application opens, I see the MainMenuController's view come up. At this point I began to wire the IBOutlets and IBActions in the pasted view in the new xib file. Although I see the IBOutlets in the File's Owner and connect them properly, the function for the IBAction is never called when I press the button.
Possible errors that came to my mind:
(1) application window not properly set, it doesn't pass events,
(2) something is stuck or lost while copying the view, still pointing to the old owner
(3) something wrong stuck in xcode project
What do you think the problem could be? Is it one of the above? How can I solve this? Any help is appreciated.
Thanks in advance.
Your creation of the main view controller:
mainMenuController = [[MainMenuController alloc] init];
makes no reference to the XIB. So you're doing a purely programmatic creation with no reference to whatever may or may not be in the XIB. Hence your view controller appears to work but none of the outlets or actions are wired up. You may be making reference elsewhere, but I guess not appropriately.
Probably you want:
mainMenuController = [[MainMenuController alloc]
initWithNibName:#"MainMenuController" bundle:nil];
That'll explicitly use whatever is in the XIB to create the controller.
I've been banging my head with this error for the last 5 hours. I have done all the googling I could yet none of the solutions seem to work for me so I will explain my particular situation and see if you guys can pick out what my issue is.
My main UI is a View with 6 Views inside of it. Each view contains an image and a label inside of it. Am I allowed to do this to contain objects together?
Anyways, I erased all my connection one by one from the File Owner and started over again. I pressed ctrl and dragged the mouse over to the main view to attach it to my view. Ran the project: great, no errors.
Connected one of the sub views, bam! Error pops up right away.
My File Owner's custom class is set to my UIViewController class.
I have the IBOutlets defined properly in the header, and synthesized in the implementation.
Let me know what you need to help me out.
** EDIT **
I set a breakpoint and found the line marked with --> <-- to be the culprit:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds];
self.viewController = [[UIViewController alloc] initWithNibName:#"View_main" bundle:nil];
self.window.rootViewController = self.viewController;
--> [self.window makeKeyAndVisible]; <--
return YES;
}
And the error thrown by the compiler is:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x6c6a0d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myView.'
All help welcomed!
check this link you'll find the answer here
The error “this class is not key value coding-compliant for the key XXX” usually occurs when loading a nib that refers to a property that doesn’t actually exist. This usually happens when you remove an outlet property from your code but not from the connections in the nib.
My File Owner's custom class is set to my UIViewController class.
This is ambiguous, and clashes with:
self.viewController = [[UIViewController alloc] initWithNibName:#"View_main" bundle:nil];
You are using a "vanilla" UIViewController rather than your custom subclass (whose class name you haven't mentioned). When the nib is loaded and it attempts to connect your outlets, they do not exist, so the exception is raised. Change the alloc/init to use your UIViewController subclass:
#import "View_main.h"
...
self.viewController = [[View_main alloc] initWithNibName:#"View_main" bundle:nil];
And ensure that the custom class of your view controller is set to View_main in the nib as well.
The reason I ask is because I was doing the following in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
PageViewController *pageViewController = [[PageViewController alloc] init];
[window addSubview:pageViewController.view];
[pageViewController release];
[window makeKeyAndVisible];
return YES;
}
But, when I tried to scroll the pageView, whose controller implements the UIScrollViewDelegate protocol, I got an error like:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL scrollViewDidScroll:]: unrecognized selector sent to instance 0x5f42a80
When I took out [pageViewController release];, this error went away. This is weird to me because window should retain ... OH GOD!!! duh... it retains the pageViewController's view, not the pageViewController.
I get it now why it's wrong to release pageViewController. Silly me... I think it's time for a break.
It looks like you figured this part out, but the answer to your question is no, UIWindow does not randomly remove its subview AFAIK. In this case, it's retaining pageViewController.view not pageViewController. So, you shouldn't release pageViewController nor should you release pageViewController.view because pageViewController.view will automatically get released when pageViewController is released. I don't see where you are releasing pageViewController. I recommend making it an ivar of the AppDelegate and then releasing it in the AppDelegate's dealloc method, as you've probably done with window. The dealloc method never gets called, so pageViewController (and window) will never explicitly get released anyway, but making pageViewController an ivar is better style IMHO. Either way, I'll bet they get cleaned up when the application terminates.