What is File’s owner in XIB in this case? - ios

I've searched for similar questions for quite a while, most of which mentioned UIViewController's xib stuff. I tried to add a xib file for my custom viewController model,and found that its Xib’s File’s Owner should be my custom viewController model's class--that is reasonable. But why the situation differs when i create a xib for my UIView model-- an example as follows:
I create my UIView model which named "KWView"(KWView.h and KWView.m)
then i create xib for this model, initializing it by
KWView *oneView = [[[NSBundle mainBundle] loadNibNamed:#"KWView" owner:nil options:nil ]lastObject];
This Xib’s File’s Owner name is “NSObject”(then i try any other more,whatever i choose, it runs smoothly),and there, i choose the view’s Custom Class as “KWView”[This xib named "KWView.xib"]
Questions are :
1.Whatever i change the Xib’s File’s Owner name of my custom view, it works. If so, what the work does this File’s Owner do here, or saying, why can this happen?
2.Generally, should i set the custom view's Xib’s File’s Owner to my custom view's class or the viewController's class which this view is going to be added to ? or just set it "NSObject"?

The answer to your question depends how you intend to extract the view from the nib at nib-load time. You are going to extract it, as you have helpfully shown us, like this:
KWView *oneView =
[[[NSBundle mainBundle] loadNibNamed:#"KWView" owner:nil options:nil]
lastObject];
That means you aren't using the owner: for anything here — it is nil. Therefore you can leave the nib's file's owner at NSObject.
The purpose of the File's Owner is to permit you to establish, in the nib, Action and Outlet connections between the view (or its subviews) and the object that will be the real owner at load time — like a view controller (owner) and its view (the main view of the view controller). But in your case, there is no such real owner and no such Action or Outlet connections.

Related

Is there a shortcut to accessing a xib's initial attributes?

I do a lot of animations with UIKit and I frequently store any animated view's initial frames in viewDidLoad to always have a reference to the frame as it appears in a xib.
This is kind of smelly and seems like the kind of thing that would be automated, but I can't seem to find any info on this. Is there a property on UIView that stores initial xib frame sizes? Or maybe a UIKit utility method that scans the xml of a xib for it's attribute values by name?
So while I could not find any way to access an interface builder file's initial attributes (unless you count writing an IB XML parser a way), I found a brilliant alternative from Do I need to set heightForRowAtIndexPath if I am using a custom UITableViewCell?. Instead of accessing some constant values from an object itself (I was hoping for a self.attribute.nib.value), you can make two outlets per IB object- one for manipulating, and one for a prototype- which will hold all the original values of the xib.
To makes things simple, just create an(other) outlet for your nib and override its getter.
For example, if we have a LargeCell.xib, we would create an outlet for largeCell and another for largeCellPrototype.
Then we would make a lazy accessor for this prototype to ensure the prototype is not nil and only loaded once.
- (LargeCell*)largeCellPrototype
{
if (!_largeCellPrototype)
{
[NSBundle mainBundle] loadNibNamed:NSStringFromClass([LargeCell class]) // Presuming you don't name files with reckless abandon
owner:self
options:nil];
}
}
now getting the initial values is as simple as
CGFloat initialViewHeight = self.largeCellPrototype.frame.size.height;

Is it possible to access/manipulate the constraints in a nib file from the view it's loaded into?

Example project: http://cl.ly/1g1L3E2Z0r1c
I create a nib file and then create some views in it, which I then load into another view controller. In the view that I bring in, it's a subclass of UIView where I have outlets set up for its properties. I have one specifically for its constraint from distance from the top.
But when I try to access it in code (like as follows), I can't, it states it's null:
self.tutorialScreen3.textLabelDistanceFromTop.constant += 150.0;
NSLog(#"%#", self.tutorialScreen3.textLabelDistanceFromTop);
What am I doing wrong?
In this line
[[[NSBundle mainBundle] loadNibNamed:#"View" owner:nil options:nil] lastObject];
you're loading the last view from your View.xib file, and it's view 3, but you're property textLabelDistanceFromTop is not connected with this view, but with view 2.
You just need to make in view 3 the same constraints you made in view 2 and to connect the textLabelDistanceFromTop property with appropriate constraint in view 3, and it wan't be nil any more.
I already did this in your project, so you can download it from this location http://goo.gl/gGvIkn

Nib from different class

I have tried several other examples, on this site and others, but for the life of me I cannot get this to work.
I have a NIB file which is a part of the class "ViewController2". I need to use a few of the views in this NIB file in my "ViewController1" class.
Each time I call
[[NSBundle mainBundle]loadNibNamed:#"ViewController2" owner:self options:nil];
it causes a crash, saying that one of my UIButtons is not KVC compliant, but I have properly linked all the buttons and outlets, to no avail.
Any help would be extremely appreciated! Thank you in advance!
that is faster at least 3 times than NSBundle:
ViewController2 *_viewController2 = [[[UINib nibWithNibName:#"ViewController2" bundle:nil] instantiateWithOwner:nil options:nil] objectAtIndex:0];
it will load the nib file and it will create a new instance of the ViewController2 class.
NB: if you'd like to use an already existing instance of the ViewController2 class for the nib, you will need to set that instance as owner.
When you load a nib and set the owner: property to self, iOS tries to wire up the outlets with KVC. If you don't have a UIButton with a keyPath that matches the one in the xib file inside of the class you're currently in, you'll get the crash. You need to set owner: to nil.

setting file owner of a xib file

Hi I am reading a book where I had to deal with such situation.
I created a XIB file named HeaderView.xib. Then I connected the File Owner of this XIB
file to ItemsViewController. All is fine so far. I also connected
some outlets of the ItemsViewController with views on the XIB.
Now, in the ItemsViewController I had to call such code:
- (UIView *)headerView
{
// If we haven't loaded the headerView yet...
if (!headerView) {
// Load HeaderView.xib
[[NSBundle mainBundle] loadNibNamed:#"HeaderView" owner:self options:nil];
}
return headerView;
}
Code above would set headerView outlet of ItemsViewController point to the corresponding
view on the XIB file (the one I made connections with on XIB file).
My question is, why did I have to, two times, specify the owner? (e.g., once in the XIB as I mentioned in the start of this port, and second time, above in the code, e.g., owner: self).
You did not specify the file owner twice:
The first time (in the XIB file) you specified the type of the file owner; this is necessary for the Interface Builder to know which outlets it can connect.
The second time (in the Objective C code) you specified the instance of the owner. This is necessary at runtime to know the object into which the outlets are connected.
Specifying the owner in the XIB tells Xcode what the controller understands (what outlets it has) so that it can offer the connections to you. This is at a class level.
Specifying the owner in code tells the unarchiving process which instance of the controller is actually going to fulfil that role and should therefore have the connections established to the new instance(s) which are unarchived from the NIB.
I found it... When the world is not using XIB(s) anymore...
Open the XIB or NIB file in your favourite text editor
you will find this line there...
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MyCalssName">
Change the class name, save the file and your file's owner will be changed.
Caution: Close Xcode (To auto reload the changes) and also take a backup in case you mess up something.

How to get a reference to an object in a .nib file?

so far I have done most view programming in code, but it really is cumbersome to position buttons perfectly in code. I searched for some time, maybe I'm using the wrong words for my search? Anyway, I created a UI in a nib file, it has several buttons. I loaded the .nib file into my view like this:
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:#"UCMenuView" owner:self options:nil];
UIView *menuView = [nibViews objectAtIndex:0];
self.delegate = (id<UCMapviewDelegate>)delegate;
// another controller does the view switching, so I'm sending him the view
[self.delegate pushView:menuView];
This is 'fine'. But I don't understand how I get a pointer to my buttons. I know about IBOutlet, but how do I connect them to the elements in the .nib? How would I connect this #property (strong, nonatomic) IBOutlet UIButton *calendar;
to a specific button in the .nib?
I tried to ctrl-drag (from that little points on the left side of the #property, but that does not work (from neither side). Excuse me if this is an easy question, but I couldn't find a clear explanation
thanks for your help
Instead of just a UIView *menuView, you need to create a custom
UIView subclass for that, e.g. UCMenuView. Define your properties on this custom
class.
Open your .xib file in the editor, select the File's Owner in
the left column and set its Custom Class in the identity
inspector to UCMenuView.
Right-click the File's Owner in the left column, and connect
your IBOutlets.
Check out this tutorial:
http://developer.apple.com/library/ios/#documentation/IDEs/Conceptual/Xcode4TransitionGuide/InterfaceBuilder/InterfaceBuilder.html
or
http://www.hongkiat.com/blog/ios-development-guide-part2-your-first-app/
Kind regards,
Bo
See Apple's documentation: Creating and Connecting an Outlet and more generally Designing User Interfaces in Xcode.

Resources