Issues Using .xib With Storyboard - iphone

Hey I'm trying to open a view controller that is designed using a xib interface file. I am using the following lines of code to generate the controller from within a view controller created as a storyboard component.
YourViewController *viewController [[YourViewControlleralloc] initWithNibName:#"ViewControllerName" bundle:nil];
[self presentViewController:viewController animated:YES completion:nil];
I have never set up a view controller with a .xib before nor have I ever linked to one via storyboard so anything could be wrong. Here is the error I am getting when I try to present the view.
2013-05-17 13:06:45.120 Coffee[8991:907] * Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason:
'-[UIViewController _loadViewFromNibNamed:bundle:] loaded the
"PeekPagedScrollViewController" nib but the view outlet was not set.'

Set the File's Owner in the .xib to the class of your view controller (perhaps it is called PeekPagedScrollViewController).
Then connect its view outlet to the main view in the .xib file.

It was connected properly I had just forgotten to declare an initWithNibName method and therefore it crashed when I called it from storyboard. Silly mistake but thanks for all the great feedback #matt

Set the Storyboard view controller custom class to your class name (the one your xib is also referencing), then in that same class, simply override initWithCoder with:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [[super initWithCoder:aDecoder] initWithNibName:#"YourCustomViewControllerXibsName" bundle:nil];
if( self ) {
}
return self;
}
This will enable you to design layout and segue transitions in Storyboard, but design your layout in a standalone nib file.
Storyboard will handle instantiation, but when initWithCoder: is called, initWithNibName: will be the method that instantiates self via the xib.

Related

Modal segue not working from code

I've already spent the whole day in an issue and did not find a solution yet. I have a UITabBarViewController and I am trying to fire off a modal segue from one of its tabs. I've already created the view I want to segue to, created the segue itself (from the tab's view controller to the target's view controller) and the identifier. In order to test my segue I created a UIButton in my tab and wrote the following code on its action:
[self performSegueWithIdentifier:#"showProductInfo" sender:self];
The modal segue worked fine. But if I try to write the same code to be performed somewhere else (inside a specific method that is called after I receive a web service response) the segue simply does not work. I get the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver () has no segue with identifier 'showProductInfo''
This is driving me crazy! Any help is more then welcome.
Editting:
Some additional findings:
If I take off the performSegue from the method I am currently using (which by the way is called by DidFinishLoading) and put it on ViewDidLoad the segue is performed successfully.
Thinking that it could be a thread related issue I included the performSegue inside a dispatch_async(dispatch_get_main_queue()... But the error is the same !
If your destination viewcontroller is inside a navigationcontroller, then take a look at this question:
http://stackoverflow.com/questions/8041237/how-to-set-the-delegate-with-a-storyboard
Furthermore, from the error it looks like the segue you are trying to perform is not attached
to the viewcontroller you are starting from. So,Try to remove the seque and drag it from the
viewcontroller.
The current view controller must have been loaded from a storyboard. If its storyboard property is nil, perhaps because you allocated and initialized the view controller yourself, this method throws an exception.
Make sure you have Storyboard ID for your destination VC (in this example myViewController).
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"myStoryboard" bundle:[NSBundle mainBundle]];
UIViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:#"MyController"];
[self.navigationController pushViewController:myViewController animated:YES];

_loadViewFromNibNamed called even though no nib associated with UIViewController

I have a UIViewController subclass which I am instantiating and trying to push on to the navigationController like so :
MenuVC *menuVC = [[MenuVC alloc] init];
[self.navigationController pushViewController:menuVC animated:YES];
I don't have a nib file associated with this class and so just doing a simple ..alloc] init] instead of initWithNib:bundle:.
I am still getting a crash on the pushViewController call and the trace says this
reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "MenuVC" nib but the view outlet was not set.'
I don't see why this could be happening. I have other view controller which loads fine with the same method.
I think I found the answer to this in Apple's Docs :
A view controller has an associated nib file if the nibName property returns a non-nil value, which occurs if the view controller was instantiated from a storyboard, if you explicitly assigned it a nib file using the initWithNibName:bundle: method, or if iOS finds a nib file in the app bundle with a name based on the view controller’s class name.
So, this means the OS actually tries to load the nib if it finds one. I did have a nib in my bundle with same name as VC but had not associated it's File Owner.
The real problem is that the Viewcontroller have a view that comes in default and somehow that connection of IB to class view->view went missing and hence the error
This might not be an "answer" but this was resolved. I just removed the whole file and added a new file with a different name and it worked.

subclassing UITableView so it doesn't need a xib

I made a XIB that only consisted of a UITableView in IB. It was brought to my attention that it is possible to subclass UITableViewController and do away with the xib entirely.
My question is, how do you do this?
So far the only thing I have changed is my .h to be...
#interface MyView : UITableViewController
and removed my XIB. Obviously I get an error that states
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Could not load NIB in bundle: 'NSBundle (loaded)' with <path>
name 'MyView''
so my question is, what else is left in order to accomplish this subclassing correctly?
There are two ways to set up your view controller in iOS.
With a .xib file: You instantiate the view controller with -initWithNibName:bundle:, passing the name of your .xib file as the first argument, and (unless you're doing some advanced stuff) nil as the second argument . The OS will look for your .xib file and unserialize it into a bunch of objects and attach them to your view controller. Then the OS calls your view controller subclass's -viewDidLoad: method, where you finish setting things up.
Programmatically: You instantiate the view controller with -init, or for a table view controller, initWithStyle:. The OS then calls your subclass's -loadView method, where you manually instantiate your view hierarchy.
It sounds like you just need to instantiate it with -initWithStyle: instead of -initWithNibName:bundle:.
If you had a ViewController without a .xib you could just create a tableview in the view did load or something.
UITableView *table = [[[UITableView alloc] initWithStyle:UITableViewStylePlain] autorelease];
table.dataSource = self;
table.delegate = self;
table.frame = CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:table];
And then you just need to implement the proper delegate and data source methods like you would in a UITableViewController.

Universal UIViewController

Please help me, I never made universal UIViewControllers with xib for iPhone/iPad. How I can create class with .m and .h files and _iphone.xib and _ipad.xib?
I was try to create xib manually and create outlets for view, but after pushing this controller I had uncaught error:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "FullNewsViewController" nib but the view outlet was not set.
Thanks!
The problem, what I can see from the error you posted, is that you have not set the owner properties of the NIB correctly.
Your nib files does not seem to have the correct file's owner and thus can't set the view on the view controller.
Open the nib, and go to File's Owner in the left since of the screen. Set the Custom Class property to the class of your viewController.
The right click on the File's Owner again and drag the view property to your view.
You should follow Apple iOS App Programming Guide
Creating a Universal App
Here you will get some tips, how to create Universal Application.
Hope this will help you out.
REview this link may be helped you...
http://elusiveapps.com/blog/2011/10/converting-iphone-apps-to-univeral-ipad/
if the view controller can easily be used for both ....
MyViewController.h
MyViewController.m
MyViewController~ipad.xib
MyViewController~iphone.xib
Set the File's Owner in both the xib files to your UIViewController subclass and connect up the view + anything else you want connected.
When I init my view controller this is all that's required
MyViewController *viewController = [[MyViewController alloc] init];
// OR
MyViewController *viewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
The Apple docs for UIViewController state that if you provide a xib with the same name as the view controller it will be loaded. The ~ipad and ~iphone ensure that the correct xib is loaded.

iOS - Interface Builder Outlets Not Initialized

I have created a view in Interface Builder with some labels and text as IBOutlets. I can view this screen perfectly when I segue to it from another view that I have defined in my Storyboard.
However, I have another XIB and an associated UIViewController that I want to access that view from. Because my XIB is not in the Storyboard, I cant segue to it. Instead I have to execute the transition programmatically.
PlantDetailViewController *plantDetailVC = [[PlantDetailViewController alloc] init];
[self.currentNavigationController pushViewController:plantDetailVC animated:YES];
When this code is executed it transitions to the view but the view is just blank. I have debugged the code and it enters viewDidLoad and viewWillAppear however all my IBOutlets are NIL....so nothing it showing up on screen!
Can anyone tell me why they might be NIL and how I can initialize them?
Thanks
Brian
It sounds like you're saying you have a PlantDetailViewController set up in your storyboard, and some OtherViewController that was created outside of your storyboard. Now you want OtherViewController to instantiate the PlantDetailViewController that was set up in your storyboard.
Let's say your storyboard is named MainStoryboard.storyboard.
First, you need to set the identifier of the PlantDetailViewController in your storyboard. You do this in the Attributes inspector, under the View Controller section. Let's say you set it to PlantDetail.
Then, in OtherViewController, this should work:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
PlantDetailViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"PlantDetail"];
[self.currentNavigationController pushViewController:vc animated:YES];
-init doesn't load a nib file for you, if you want to load a nib use -initWithNibName:bundle:
If you use nib naming conventions you can pass nil to load a nib whose name matches your class and the default bundle, i.e. [[PlantDetailViewController alloc] initWithNibName:nil bundle:nil], see the docs for -nibName for details.