How do I use InterfaceBuilder files in Xcode subprojects? - iphone

I'm developing an iPhone app that is a "module" of another launcher (it doesn't launch from the iPhone home screen). To add this module to the launcher, I have to drop in the xcode file into the parent xcode project (creating a subproject). The subproject uses a NIB file as its view controller and the subproject loads the file using initWithNib:
root_view_controller = [[UINavigationController alloc] initWithRootViewController:[[LMU_IP_RootView alloc] initWithNibName:#"LMU_IP_RootView" bundle:nil]];
When I try to run the parent project, it crashes with:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle [...] (loaded)' with name 'LMU_IP_RootView''
I'm guessing its because it can't find the NIB file because the root bundle is now the parent project instead of the subproject. I could include the NIB in the parent project and that fixes the error, but doesn't solve my problem.
So my question: How do I use InterfaceBuilder files in a subproject? Do I have to specify a bundle? How do I specify a bundle that refers to this subproject?
Thanks!

When bundle is nil, the search is performed in the main bundle, not in your subproject bundle. I'm not entirely clear on your app architecture, but try specifying the bundle containing the class as the bundle to search:
NSBundle *classBundle = [NSBundle bundleForClass:[LMU_IP_RootView class]];
id vc = [[LMU_IP_RootView alloc] initWithNibName:nil bundle:classBundle]
root_view_controller = [[UINavigationController alloc]
initWithRootViewController:vc];
[vc release];
Note that a nil nib name defaults to "ClassName.nib", so LMU_IP_RootView.nib will be searched for in this case.
It's generally better to override -init in your view controller class so it performs the correct lookup. Then client code doesn't have to worry about what nibs the class needs.

Related

can't load nib error message

I am getting a very annoying error message:
'Could not load NIB in bundle: 'NSBundle (loaded)' with name 'SingleStoryViewController''
Any idea why? That SingleStoryViewController nib is there available in the project.
I am not sure which code to post, but here's what I have:
if ([viewType isEqualToString:kSingleStoryView]){
viewController = [[SingleStoryViewController alloc] initWithNibName:#"SingleStoryViewController" bundle:nil];
}
Please check the following points:
1) You have spelled the nib filename correctly.
2) You have specified "SingleStoryViewController" as the Parent class for the file's owner object in nib file.
3) You have connected the view outlet in the nib file to the UIView.
Please let us know if any query.
Is the name of the NIB exactly SingleStoryViewController.xib
Is it marked to be copied to the bundle
Is it in the Resources folder
Open the .app bundle -- is it there? In the Resources folder?

Could not load NIB in bundle - inspiration needed

I'm currently seeing this error:
MonoTouchException: Objective-C exception thrown. Name:
NSInternalInconsistencyException Reason: Could not load NIB in bundle:
'NSBundle </Users/imac/Library/Application Support/iPhone
Simulator/5.0/Applications/5D8B4B51-9FB2-4331-BFEB-B1A0AC77DF42/Tutorial.app>
(loaded)' with name 'MyFirstView'
I've looked through lots of other questions like:
NSInternalInconsistencyException Could not load nib in bundle
Could not load NIB in bundle
and lots of others
But I can't see that any apply here - they are mainly about file naming issues and my Nib does appear to be in the output package file with the correct name.
I'm using MonoTouch 5.2.5 and xcode 4.2, and targeting SDK5
Does anyone have any ideas about what I could try to fix this?
I have faced the same Problem today. I refactored (rename) viewController to myCustomViewController and got this error. When I searched in my project files, I saw that I have used self.viewController = [[[MyTableViewController alloc] initWithNibName:#"viewController" bundle:nil] autorelease];
NibName was changed but in #" " it was old name. so I changed it to
self.viewController = [[[MyTableViewController alloc] initWithNibName:#"MyTableViewController" bundle:nil] autorelease];
and error was removed. Do it and hope your error will be removed.
Vote up if it helps.
The problem eventually it seems was somewhere in the extended toolchain - somewhere between MonoDevelop, xCode4 and the simulator.
Restarting everything, and resetting the simulator cleared the problem.
Later in the same chain I've seen smaller issues with "old NIB file outlets" persisting on the simulator even after I've definitely deleted them and rebuilt - so something is still going wrong somewhere... but a clean solves it each time.
So I had a similar solution in MonoDevelop. I created an empty mono touch project. When I deleted the xib file associated with the auto created project, i ran into problems. Even though I created a new view and connected the outlet to that controller, I had to go back and recreate the xib file associated with the controller (with the same name) again, and then connect that original view and controller via the outlet

'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the GameView nib but the view outlet was not set

This is not the same situation as the multitude of other similar questions here.
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the GameView nib but the view outlet was not set.'
You might be thinking "do as it says, connect the File's Owner to the View in IB!". But the thing is, I don't even HAVE a GameView.xib in my project or even in the project directory.
I do have a "GameViewController.m" and matching "GameViewController.xib" in my project. Using that GameViewController is what brings up this error, but I don't understand where it gets the idea to try and load "GameView.xib". Shouldn't it use "GameViewController.xib" instead?
If I grep my project directory, I do see it referenced from "UserInterfaceState.xcuserstate".
<string>file://localhost/Users/bemmu/Dropbox/b2/iphone/ValleyStory/ValleyStory/GameView.xib</string>
This mentioned file does not exist. I might have had a file with that name before and renamed/deleted it, but it's not being referenced to from anywhere that I can see in IB.
Did I manage to confuse xcode?
My solution was a little different.
Click on the xib in interface builder
Select File's Owner on the left
Open the File's Owner's connections inspector
If the view property isn't yet wired, control-drag it to the view icon (under the file's owner and first responder icons).
Check any nib files you're using (like MainWindow.xib). If you are loading GameViewController from a nib, check the file it's loading from (under the info tab in the inspector). Make sure it's set to "GameViewController" and not "GameView".
I had this issue as well, but had to solve it a different way. Basically, I have a view controller name MainViewController, which has a xib named MainViewController.xib. This nib has it's view property set to the File Owner which was MainViewController.
I also made a MainView.xib that contained a view that was going to be programmatically added to the view defined in MainViewController.xib and it's view. It basically encapsulated an internal view that would be in the MainViewController.xib's view, and also had it's File Owner set to MainViewController.
So basically, I wanted MainViewController.xib to load as the nib for the MainViewController object, and inside MainViewController, at some later point, I would add the internal view specified by MainView.xib.
A couple issues arose:
1.) I found in the Apple docs that when loading a view controller via storyboard or nib:
"If the view controller class name ends with the word “Controller”, as
in MyViewController, it looks for a nib file whose name matches the
class name without the word “Controller”, as in MyView.nib.
It looks for a nib file whose name matches the name of the view
controller class. For example, if the class name is MyViewController,
it looks for a MyViewController.nib file."
Therefore, you cannot have a nib called MainView.xib if you also have a nib called MainViewController and want MainViewController.xib to be the primary nib for MainViewController.
2.) Even if you delete MainView.xib or rename it to something else (MainInternalView.xib in this case), you MUST delete / clean your iOS simulator as the old nib file (MainView.xib) will still remain in the application. It doesn't overwrite the whole application package when you rebuild / rerun your application.
If you don't want to reset your content settings (perhaps you have some data you want to preserve), then right-click on your application in your iOS Simulator folder, Show Package Contents, find MainView.nib, and delete it. Xcode will NOT do this automatically for you when you rebuild, so we need to manually remove the old nib.
Overall, don't make nibs named MainViewController and MainView, i.e. nibs with the same prefix. Call MainView.xib something else, like MainInternalView.xib.
I recently solved this issue. Make sure you back up your project before following the steps given here (just in case). These steps solved my issue
Quit Xcode
Navigate to UserInterfaceState.xcuserstate located at .xcodeproj/project.xcworkspace/xcuserdata/<username>.xcuserdata and delete the file.
Reopen Xcode. Xcode will create a new UserInterfaceState.xcuserstate which will be clean.
In my case this error was produced by dumb mistake - I delete _view view
In my case, I was not using a xib at all. I needed remove the .m file from Build Phases > Compile Sources and added it back.
Given you referenced it previously it sounds like xcode hasn't ackowledged it no longer exists. From the Product menu select "Clean" and then "Build" hopefully this will get past the old reference for you.
Face the same Problem, had to change the view's name in code:
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"WrongViewName" bundle:nil];
To
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"RightViewName" bundle:nil];
I had multiple views, and by accident (I don't know how this happenned) but my background view didn't have a file owner, so for anyone else who has this problem in the future, make sure all your views have a file owner.
I was gettint the same error then check the classname from interface builder and see that I typed the view controller class name at the custom class attribute.
UIViewController searches for a nib with the same name as the controller when passed nil to initWithNibNamed:bundle: Check that the file name that you pass to the initializer is correct and exists!
For example:(e.g. [[CCVisitorsController alloc] initWithNibName:nil bundle:nil] then UIViewController tries to load nib with name CCVisitorsController as default.
If that file does not exist then the error you mentioned is thrown.
I had this problem because I was doing something bad in
(id) initWithCoder:(NSCoder *) coder
which the NIB loads.

Getting error in console for iPad application

I am getting an error while I tried to push ViewController in table's didSelectRow in iPad app.
Error which I get is:
** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle /Users/abc/Library/Application Support/iPhone Simulator/4.2/Applications/CFC7803E-4E44-45BF-9F47-``E24DDB44F286/SampleIpad.app> (loaded)' with name 'DetailView''
Code in table's didSelectRow method :
DetailView *detailViewController = [[DetailView alloc] initWithNibName:#"DetailView" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
What can be done?
To do so, Right click the viewController .m file in Xcode
Click GetInfo
Go to Targets tab and check if the checkbox next to your target project is checked? If not, do check that checkbox.
Clean and Rebuild your code.
This would work for you.
This error is due to the missing nib file.Check whether your application folder on the disk contains the DetailView.xib file. If it is present you may try using [NSBundle mainBundle] instead of nil in the bundle parameter.
Try this
[NSBundle mainBundle];

Why can't I load a nib in my bundle in my iPhone static library?

Let me preface this by saying that I'm a very raw iPhone developer.
I'm making a static library that can be used in iPhone apps. It needs to show a view but static libraries, as I understand it, cannot include nibs (or xibs, in my case). So, I have created a separate bundle containing the xib I need. I then include the bundle along with the static library in the app. I want to initialize a class that extends UIViewController using the xib in question.
I have the following code in my library:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"Mobtest" ofType:#"bundle"];
NSBundle *mobtestBundle = [NSBundle bundleWithPath:bundlePath];
NSLog([#"bundle path: " stringByAppendingString: [[NSBundle bundleWithPath:bundlePath] bundlePath]]);
sharedInstance = [[MTFeedbackViewController alloc] initWithNibName:#"MTFeedbackViewController" bundle:mobtestBundle];
The bundle path outputted by NSLog is the correct path for the bundle in the compiled app. Unfortunately, I cannot initialize the UIViewController and instead get the following error:
2010-08-20 22:08:16.102 MobtestLibSampleApp[2332:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] was unable to load a nib named "MTFeedbackViewController"'
Does anyone have any suggestions of why the xib cannot be loaded? Perhaps something in it is linked incorrectly? Is there any place where I can get additional debugging information?
Have you considered ditching the nib and just building your view in code by implementing -loadView in your view controller? If you don't have many views, and/or they aren't complicated, this would be easier for users of your library, since they wouldn't have to worry about including a bundle along with your lib.
For debugging purposes, you can override -loadView in your view controller and inspect self.nibName and self.nibBundle to make sure that your controller is getting the resources that you're passing in. Just remember to call [super loadView] so that your nib actually gets loaded. (Note that if you override loadView to build your view, and set the view property of your controller, you should not call [super loadView].)
The docs say that the nib inside your bundle should live in the "lang specific project dir" or in the "Resources" sub dir. Double-check your bundle target in Xcode to make sure that your nib is being copied into the correct place (either the 'Projects' or 'Resources' subdir) in your bundle. Also, try inspecting the contents of your bundle in the loadView method:
NSLog(#"nib path inside bundle: %#", [self.nibBundle pathForResource:#"MTFeedbackViewController" ofType:#"nib"]);
I hope you actually mean nib. xibs are an XML serialization for editing by Interface Builder; they're compiled to xibs during the build process. iPhone nibs appear to be a binary plist (I don't think binary plists existed before about 10.3, I don't know what happened before that).
Try NSLog(#"%#",[mobtestBundle pathForResource:#"MTFeedbackViewController" ofType:#"nib"]).
Also note that the first argument to NSLog is a printf-style format string, so you invoke undefined behaviour if your bundle path contains a %.