Loading UIView from NIB - ios

I have a view controller V which is part of a story board. On its viewDidLoad method it attempts to load a few views from a NIB (not a storyboard). The idea is to "assemble" some of the view using these "subviews".
However, when I try to load a view like this:
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:#"x"
owner:self options:nil];
I'm getting an exception saying 'this class is not key value coding-compliant for the key yyy.'
This is because the view in the NIB has a custom view controller, which has an outlet to a component in this view, which is connected in the NIB properly.
What am I doing wrong here?

right click on your fileOwner viewController in interface builder and then delete yyy outlet, you have an outlet connection, which is not existed or deleted
Update screenShote added
Look at this screenshot the button has 2 outlets, but yyyy is not existed in the viewController. you should delete this outlet

Related

Loading Nib containing UITableView from a UIViewController causes key-value coding compliant error

I have a UIViewController setup in storyboard. I'm trying to load a Nib that contains a UITableView. Before I even get to initWithFrame: or awakeFromNib I get a this class is not key value coding-compliant for the key tableView. error when calling:
MyView *view = [[[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:nil] firstObject];
I know that the connection between my file's owner and the tableView outlet is trying to connect, and fails causing the error. The nib is clean and the outlets don't have any extraneous references. What is causing this error?
Every time I have come across that error it has been because the view has a reference to an outlet in code that does not exist anymore. Are you sure your view (the storyboard scene or the nib itself) don't have orphan outlet references?

Nib loaded, outlets missing

In my project some UITableViewCell have some complex subview structure and gesture action, so I decided to use a layer of "cell controller" objects (subclasses of NSObject) to manage the cells and cell-layer gestures, as well as drawing the cell in a xib file.
Now when I load the cell from the nib with cell controller as its owner (the xib is properly set up) I found the outlets not connected. Why?
Or, is there any method that is called on the owner object when a nib is loaded and outlets is set up?
Nib is loaded like this:
cell = [[NSBundle mainBundle] loadNibNamed:#"HistoryCellActive"
owner:self
options:nil][0];
The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.
You may try to override awakeFromNib method in the HistoryCellActive implementation file and put a breakpoint here. If cell xib file is correct the debugger stops in this breakpoint and you can check all cell's outlets. If no then you have to check xib for mistakes.
Don't forget to call [super awakeFromNib]; at the beginning of awakeFromNib implemetation.

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

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.

iOS who is file owner of subview?

I am newbie in iOS development and I have a problem to understand file owner logic.
I have this situations:
I have two views (View_iPad, View_iPhone) and their controllers (ViewController_iPad, ViewController_iPhone). Based on a device where app is launched, particular view and its controller is used. Then, I add a subview from xib file to this view (it doesn't matter if iPad or iPhone view is used). Let's say that there is a different position of this subview in iPad and iPhone view. This subview contains some labels, so I have to create IBOulets in subviews controller.
If I understand, according to apple's logic, file owner of view is a controller (file which has access to this view and can communicate with it). So each of 3 views (iPhone, iPad, subview) has its own controller, it means that these controllers are file owners of these views.
But when I load subview with code:
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:#"subview" owner:self options:nil];
and add it as a subview to iPad/iPhone view, there is a problem because this subview contains IBOutlets for labels and this labels are in subview controller and not in a iPhone/iPad controller.
This error is shown then:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFConstantString 0x7ab4> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.'
How can I solve this? I tried to put as a owner #"subviewController" but it didn't help. Thank you.
EDIT!!:
So I was trying to solve this but still it doesn´t work. Here is a new situation:
Subview controller is owner of the subview but custom class of the root view is a class (derived from UIView) which contains outlets.
If I have in iPad/iPhone controller owner:#"subviewController", Igot this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSObject 0x715bf30> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.'
Where the view is a property from subview controller. Now tell me where is the problem. I am really desperate!
Or If I have owner:self, some window with instructions is opened with EXC_BAD_ACCESS error.
So first of all, if you have a view controller created from xib/storyboard then the view controller owns his view. If you create a custom view using xib files then the files owner will be the custom class(a subclass of UIView) but when you are creating custom views with xib files you have to link the IBOutlest to the UIView not to the files owner like you are doing when you have a view controller.
Second, your problem is not generated by the owner your problem si generated by an outlet which is wrongly linked, probably you linked an view to an outlet which is a string, so check all your outlets and their corresponding views.
The File's Owner icon in the Interface Builder-like part of Xcode (since IB doesn't exist separately anymore) is a proxy for the object that is specified as the owner when the nib is loaded. Usually, that's the object that loads the nib, typically the application or a view controller.
When you say:
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:#"subview" owner:self options:nil];
then File's Owner will be whatever object self is in the line above. If you want an object other than the one that contains the line above to be the owner, specify that object in the owner: parameter.

Add a UIView to a UIViewController with Xib

Here is what i am trying to do:
I have AViewController and it's Xib, then I add a UIView half the screen which I connect this view to B-UIView and B-UIView has its own xib where i do the design.
In other words I have a view controller with it's view which becomes the "mainview" as I add other views to it which come with its own xibs.
Hierarchy:
1 ViewController UIView (xib)
2.B-UIView (has its own xib)
3.C-UIView (has its own xib)
So is this possible if so how?
Many thanks in advance!
Yes, you can definitely do this and it's not difficult at all!
In fact, it's a pretty common way to design something in Interface Builder. You can then load your custom Xib file programmatically using loadNibNamed. For example:
[[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil];
Apple's docs talk about this in the "Table View Programming Guide for iOS".
Although their example is about creating a custom table cell, the same rules apply for any view. Have a close look at the section entitled Loading Custom Table-View Cells From Nib Files.
One thing they don't do in that example is to load the top level view. loadNibNamed returns an array, so to get that top level view that you're after, you should also do:
MyCustomView *myCustomView = [myNibsArray objectAtIndex:0];
So, your code will look like:
NSArray *myNibsArray = [[NSBundle mainBundle] loadNibNamed:#"MyCustomView" owner:self options:nil];
MyCustomView *myCustomView = [myNibsArray objectAtIndex:0];

Resources