Put the UIView in the header of the UITableView

I have a UITableView that is in my xib file. And I created such a property for the controller:

@property (nonatomic, retain) IBOutlet UITableView *myTableView; 

Now I want to have a table title (not a title for each section). Therefore, since I want to have a custom style, I created a new xib file with a view (and I connected to my controller, which implemented myTableView ).

Then I can write to viewDidLoad in my controller:

 [self.myTableView setTableHeaderView:self.myTableHeaderView]; 

where myTableViewHeader is the myTableViewHeader property in the controller.

Unfortunately, a UITableView does not display this UIView, so my question is: how can I put a UIView in a UITableView in the header?

Thanks in advance and best regards.

+7
source share
1 answer

A few things to check:

  • myTableHeaderView should also be an IBOutlet or created in your class code somewhere

  • self.myTableHeaderView should not be nil when you try to add it as a table header. If it is zero, you did not connect your sockets correctly.

  • if you developed the table header in IB in your own .xib file, then you should call somewhere (viewDidLoad is a good place):

 [[NSBundle mainBundle] loadNibNamed:@"MyTableViewHeader" owner:self options:nil]; 

The owner of the MyTableViewHeader.xib file must be your subclass of TableViewController, and you must connect the myTableHeaderView object to the corresponding File Owner output.

EDIT: in response to "what does [[NSBundle mainBundle] loadNibNamed:@"MyTableViewHeader" owner:self options:nil]; "?

This short line contains magic that will open your eyes to how XIB files and Objective-C objects work together in Cocoa (touch), bringing your iOS Kung Fu programming to completely new levels. There are two classes of Cocoa programmers who understand what it does, use and benefit from it, and those who still don't know what they are missing, and instead stumble across the desert, trying to create XIB files for their objects and never got him to work.

With this massive build up here are the details:

An XIB file (NIB) is a collection of Objective-C archive objects (and links to objects that are not actually in the XIB, such as a “file owner,” a so-called “proxy object”) and the connections between these objects. When the XIB file is loaded, these archive objects are implemented exactly in the state in which they were saved in the XIB, and then the connections between these living objects (and "proxy objects") are made in accordance with the connections recorded in the XIB file.

For example, in your standard subclass file, UIViewController.xib, you have a File Owner installed in your MyViewController class. Inside .xib is a UIView object, which usually itself contains other UIKit objects. The output of the "view" of the UIViewController class is set to the UIView object in .xib. When this .xib file is loaded, the UIView object is unarchived and becomes a living UIView object with all the properties and settings recorded in .xib. This is the "inconsistent part."

And then, because of the connection in the .xib from the owner of the file (class MyViewController) to the UIView object, the pointer to this new UIView object is stored in the "view" field of your MyViewController instance. Any other connections also present in the .xib file, such as UILabels, UIButton actions, etc., are also configured for any other IBOutlet fields in MyViewController.

It all looks like magic and happens with

 (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle 

when starting a new subclass of UIViewController.

Now the good part: you can do this by combining nib files with objects yourself! You can use the loadNibNamed:owner:options method to link any .xib file with the corresponding nil IBOutlets set in any object you want !!!

Suddenly, by creating fully customizable table view boxes, table headers, footers, as you like, you can easily write modular reusable UIView components, etc., all of which are laid out in Interface Builder.

An object whose IBOutlets names you want to fill with objects loaded from the .xib file is the owner object. Usually (but I'm not sure if this is absolutely necessary, any class with an identically typed and named IBOutlets set to File Owner can work) is a class that will be listed as the "file owner" in xib.

OK, now you have an existing owner object with nil IBOutlets (IBOutlets must be equal to zero or they will not be changed, that the "rule" is to load the XIB into the owner object. It's good that some IBOutlets are not zero, they just will not be changed when downloading the XIB file, and usually this is what you want), and you have your .xib file with the objects you want to load into the owner object. You call:

 [[NSBundle mainBundle] loadNibNamed:@"MyXIBFileToLoad" owner:theOwner options:nil]; 

.. and voila! Now any zero IBOutlets in "TheOwner" that are associated with objects in MyXIBFileToLoad.xib have been set to new objects loaded from the XIB file.

(also this method returns an array of all objects that have no analogues from xib. If you do not care about setting up any outlets, you can simply search this list for your objects by class and by tag).

So, this story is now crazy about new ways to associate Objective-C classes with objects stored in XIB files!

+24
source

All Articles