Add a UIView to a UIViewController with Xib - uiview

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];

Related

How to drag a custom view to be a private property of a custom view in Xcode 6

I am looking at creating a custom UIView called AnalogClock (from the iOS7 in Action book). I drag out a UIImageView and think I would be able to ctrl-drag to the custom UIView (AnalogView in this case). But I cannot. Do I need to configure anything else to make this possible?
This isn't working.
Just showing set to correct custom view (AnalogClock).
You can’t have views that are added in IB be properties of other views. You will need to create a separate xib with AnalogClockView as the file’s owner, and then load it from a xib in code like this:
UINib *nib = [UINib nibWithNibName:NSStringFromClass([AnalogClockView class])
bundle:nil];
AnalogClockView *clockView = [nib instantiateWithOwner:nil options:nil][0];
You may also want to look at IB_Designable, which lets you create custom views that render in IB.

Error in custom UIView class having interface loaded from .xib file

I want to make a reusable UIView which I will use in several UIViewControllers.
So I added a .xib file in my project and I drawn my interface, I added a class inherited from UIView and then I set up .xib class type same as the new class I have just added.
Next I dragged a outlet for .xib's main view in corresponding .h .
In myCustomUIView class I wrote this code to load the interface from .xib but it crashes at the line where I'm trying to load the nib file. Unfortunately compiler doesn't give me any error/reason. Please help me.
-(void)awakeFromNib
{
[[NSBundle mainBundle] loadNibNamed:#"DropDownMenuViewInterface" owner:self options:nil];
[self addSubview: self.customView];
}
Did you setup File Owner for this xib?
Check my image
Instead of subclassing root view in you xib hierarchy - make the File Owner to be your view subclass

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.

Loading UIView from NIB

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

Does XIB always need a view controller?

If I do an interface in IB must I always need a base UIViewController or can I just skip straight to a UIView ?
As of now I'm doing all my design in obj-c which makes for a bit more busy work.
If I have to use a UIViewController is there anyway to suck the UIView out of it if that's all I want?
I just want to be able to pull out static layouts from XIB instead of putting them together in obj-c.
Any suggestions are appreciated!
UIViewController has that handy initWithNib: bundle: method that makes everything so easy, but there are also ways to get objects from xibs via:
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"WhateverItsNamed" owner:self options:nil];
(and the nib array here contains objects which correspond to whatever objects are stored in the XIB file).
No, you don't need a UIViewController if it doesn't serve your needs.
After you have initialized a UINib, use its:
-instantiateWithOwner:options:
to access the nib contents. Make the nib's root object be a UIView (or subclass thereof). If you plan on making connections to File's Owner you will need to set File's Owner to a context-appropriate class.
No, you don't need to associate a UIViewController with a XIB.
First, do not add a view controller to the XIB. Then, you'd often use NSNib or UINib APIs to access the top level objects of the nib -- so you can avoid a view controller and set up any structure you'd like in the NIB editor, and programmatically access the objects in the NIB as needed.
In iOS 5, XIB are not recommended to be used anymore, you should use a storyboard instead.
And to simply answer your question, every top level view requires a view controller to be responsible for it.
All sub views can be an outlet in your view controller and be handled from there.

Resources