How can I create view controller that is defined in XIB? - ios

Sorry for perhaps noob question, guys. I'm new to iOS development.
How can I create view controller that is defined in XIB ?
When you create new class inherited from UIViewController in Xcode via "New File" and mark with XIB checkbox it creates xib file that doesn't have viewController element. But rather it has placeholder which points to UIViewController which is defined in the code.
But I see that you can create controller itself in Interface Builder and specify customClass for it.
Unfortunately it doesn't work for me. I get loaded the "EmbeddedViewController" nib but the view outlet was not set error in run-time. But I believed view property must be set by resource loader automatically since everything is defined via XIB. It works that way for TableView and its cells for example.
Could you please provide example how to do it ?
I created sample project: https://github.com/cppexpert/SampleWithNib
The controller in question is EmbeddedViewController

Create one Xib per UIViewController
Each Xib have File's Owner object for you to set UIViewController class there. Click File's Owner and choose EmbeddedViewController on it's class
Then drag main UIView not UIViewController class to there, then hook up this view with file's owner as view. UIViewController just use to drag to StoryBoard base project.
https://github.com/lequysang/gitfiles02/blob/master/SampleWithNib-master.zip

Turned out these controls exist in IB for Storyboard projects.

When you create a view controller with xib via "new file", Xcode generates an UIView and connects it with view outlet automatically. Seems like you changed something after Xcode generated the xib file. In that case you need to connect a view to the view outlet manually.

If you create a new view in xib.set the file owner to your custom class.
Or if you simply want to create a view.
Then
NSArray* test1 = [[NSBundle mainBundle] loadNibNamed:#"View" owner:self options:nil];
self.myViewFromNib = [test1 objectAtIndex:0];
Where myViewFromNib is your view object and "View" is your nib name.

Related

Subclassing a View Controller

I have a single view aplicaition on xcode with several view controllers and xib files in it. I am trying to subclass a xib file's view controller called ViewControllerPg62 as a sub class of a view controller called ViewController. How can i do this?
Thanks in advance
Why are you working with XIB files? You should be using Storyboards.
I had to go back to an old project using XIBs to see how they worked.
In an XIB you should see an entry called "Placeholders", and under that, an item called "File's Owner." That represents the object that owns and manages the views in the XIB. Select that, and then display the Identity Inspector. There will be an entry at the top "Custom Class" where you can change the class that manages this view controller.
Before changing that, I suggest you create the source file for your view controller ("ViewController.swift", in your case.) Then when you change the class of the owning object, the XIB will create an instance of your custom class when that XIB is invoked.
The approach is quite similar for Storyboards, although it's a little more coherent.

IOS Custom UIView doesn't show

I'm sorry but i'm still a bit dumb in UIViews and creating a custom one.
I have a custom view and a xib file that are connected through the XIB IB.
I want to add this view to the storyboard.
What you see in this picture is an empty view which i've connected to the custom view class
When launching the app - i see the exact same view without my custom view being loaded.. what am i missing ?
It is not enough to just link your xib view to the storyboard through the view class name. You should copy the view from your xib (open your xib, select the root view and copy) to your storyboard view controller (select the parent view and paste). You can even open (double tap the xib file in the navigator) your xib in a new window and do a drag drop to the story board. Note that all the property wirings and constrains that you had defined in the xib will be retained when you copy paste your view from xib file.
The answer is actually pretty simple.
I had a recursive init process - meaning that although i did over initWithCoder method, in the xib file, i've set the view class to be my class.
What i should have done is to make my xib file's owner to be my class instead.
And then all the loadFromNibName worked perfectly in my initWithCoder!

Connect UIView in XIB and load it using View Controller in the Story board

I have a XYZViewController (simple UIViewController in storyboard) that is loaded up with the default view. I have a type XYZView for which I have UIView in a .xib file.
In the XYZViewController class, I have defined property for XYZView as an IBOutlet. What is tricky is I don't know how to connect this property to the UIViewController in storyboard (or UIVIew in .xib file) such that —
the IBOutlet is connected to the right UIView
the view in the xib becomes an added subview for the default view of the UIViewController.
(I under the question sounds dodgy and/or I may not have the very right way to explain it, but that's the best I could.)
EDIT: Further clarification may make it easier. I just don't want to myself say:
XYZView *xyzView = [[XYZView alloc] initWithFrame...];
or
[self.view addSubview:xyzView];
Maybe that helps.
OK, from what I tell you have the following...
XYZViewController
The code of this is in XYZViewController.h and .m files.
A .storyboard file
In the storyboard file you have a view controller that you have set the subclass to XYZViewController.
A .xib file
In the xib file you have a single view that you have defined as the subclass XYZView.
Right?
I'm guessing what you have done is the following...
In the .xib file you have laid out the XYZView and put labels, buttons, etc... on it.
The view controller is being created by the storyboard. But now you want to attach the labels and buttons to it.
Right?
If all this is correct then you have a couple of options.
The easiest option
Drop the xib file. Unless that XYZView is being used in multiple places in the app (i.e. inside different view controllers) then you should really be doing all of that layout in the storyboard. Add the buttons and labels to the XYZViewController in the storyboard.
This will then allow you to connect the IBOutlets and IBActions and it will all just work because the storyboard is creating and then setting the outlets and actions.
Next option
Because you have created the view in a xib file you have to load it from that xib file in code and then add it to you view controller.
Something like...
- (void)viewDidLoad
{
[super viewDidLoad];
self.xyzView = [[[NSBundle mainBundle] loadNibNamed:#"XYZView" owner:self options:nil] objectAtIndex:0];
[self.view addSubview:xyzView];
}
Then you can do stuff like ...
self.xyzView.someLabel.text = #"This is the text";
You still won't be able to connect outlets and actions but that's because the view controller is not being created by the xib. It's being created by the storyboard.
This can get all messy though. I'd really only recommend creating a view in a separate xib if it's something that you reuse over and over (like a 5star rating view or something).
What you absolutely can't do
OK, I think I may have thought of what you are doing.
In the storyboard you have set the subclass of the view as XYZView and you are expecting it to pick up the labels and buttons etc... that you have defined in the xib file for XYZView.
This absolutely will not work, ever.
The storyboard and the xib are completely separate objects. If you want to use them together then code is involved in loading a view from a nib and then adding it to a view controller created in a storyboard.

Copy and paste storyboard controller into xib file. Supported or not?

I want to refactor out a storyboard controller to a separate xib, for better reusablity.
The controller extends UITableViewController.
I can select the controller in the storyboard, hit Cmd-C, create an empty xib file using the New File wizard, and finally paste the controller into the xib.
It seems to work ok. The UI elements are there, the outlets are there, etc. It forgets the orientation and the size (portrait, Retina 4-inch), but I can easily set that in the properties pane to the right in xcode.
However when trying to use this xib I get a crash with error message:
loaded the "MyController" nib but the view outlet was not set.
When I try to connect Files Owner to the table view (which is the top view in a controller extended from UITableViewController), xcode won't let me connect them.
My question: Is it unsupported to copy-paste a controller from a storyboard to a xib?
You are most likely jamming a tableViewController into a nib and there is no outlet to hook the view to. When you do Ctl-C in the storyboard make sure you copy the UITable not the UITableViewController. If not you can try to manually create the outlet in the controller but you might have to jump through hoops to make it work.

Add custom view in xib file

So I have a custom view created(with a xib file) and I'm trying to use it in another xib file...but it's not showing. In that xib file I have a view and I've set the custom class field to my custom view's name.
However, this view is not showing.
I don't want to draw this view programmatically, I want to use a xib file - how do I do this?
I'm not sure what code I can post up - just tell me in the comments.
I'm not aware of a method to directly drawing a custom view with a xib to another xib, but a thing you can do is:
assing the file owner to the view controller of the xib you want to put the custom one in.
assign the view as an IBOutlet of that controller.
when you need the outlet simply call: [[NSBundle mainBundle] loadNibNamed:#"your_custom_view_xib_name" owner:self options:nil];, at this point the outlet previously created will be set.
set the outlet as subview of the view

Resources