Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Put a UIView into a UITableView Header

I have a UITableView which is in my xib file. And I created a property like this for the controller:

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

Now, I want to have a table view header (not a header for each section). So, because I want to have custom styling, I created a new xib file with a view (and I connected to my controller which has the myTableView implemented).

Then I can write in viewDidLoad in my controller:

[self.myTableView setTableHeaderView:self.myTableHeaderView];

where myTableViewHeader is a UIView property in the controller.

Unfortunately, the UITableView won't display this UIView, so my question is, how can I put a UIView to a UITableView into the header?

Thank you in advance & Best Regards.

like image 894
Tim Avatar asked Feb 11 '11 11:02

Tim


People also ask

Is it possible to add UITableView within a UITableViewCell?

Implementation of adding a table view inside the cell of UItableview aka, Nested Table View. Used the Power of Autosizing table view and delegate to achieve the expansion and collapse of the cell height.

How do you add a footer in tableView?

To create a basic header or footer with a text label, override the tableView(_:titleForHeaderInSection:) or tableView(_:titleForFooterInSection:) method of your table's data source object. The table view creates a standard header or footer for you and inserts it into the table at the specified location.


1 Answers

A couple of things to check:

  • myTableHeaderView must also be an IBOutlet or created in code in your Class somewhere

  • self.myTableHeaderView must not be nil when you're trying to add it as the table header view. If it is nil then you didn't hook up your outlets correctly

  • if you've designed the table view header in IB in its own .xib file, then you must somewhere call this (viewDidLoad is a good place):

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

The File's Owner of the MyTableViewHeader.xib must be your TableViewController subclass, and you must hook up the myTableHeaderView object to File's Owner's corresponding outlet.

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

This one little line contains the magic that will open your eyes to how XIB files and Objective-C objects work together in Cocoa (touch), elevating your iOS programming kung-fu to entirely new levels. There are two classes of Cocoa programmers, those who understand what it does and use and benefit from it, and those who don't yet know what they're missing, and instead stumble through the wilderness trying to create XIB files for their objects and never quite getting it to work.

With that massive build-up here's the details:

A XIB (NIB) file is a collection of archived Objective-C objects (and reference to objects not actually within the XIB, like "File's Owner", a so-called "proxy object") and connections between these objects. When a XIB file is loaded, these archived objects are brought to life in exactly the state they were saved into the XIB, and then the connections between those live objects (and "proxy objects") are made according to the connections recorded in the XIB file.

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

And then, because of the connection in the .xib from File's Owner (MyViewController class) 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, like UILabels, UIButton actions, etc., are also set up, to any other "IBOutlet" fields in MyViewController.

This all seems like magic and happens with the

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

method when you init a new UIViewController subclass.

Now the good part: you get to do this sort of associating nib files with objects yourself! You can use the loadNibNamed:owner:options method to associate any .xib file with matching set of nil IBOutlets in any object that you want!!!

All of a sudden, creating entirely custom table view cells, table headers, footers, whatever, is a breeze, you can easily write modular reusable UIView components, etc., all laid out in Interface Builder.

The object whose nil IBOutlets you want to fill in with objects loaded from a .xib file is the "owner" object. Usually (but I'm not sure this is absolutely required, any class with the identically typed and named IBOutlets set to File's Owner may work), this is the class that will be specified as "File's Owner" in the xib.

OK, now you've got your existing owner object with nil IBOutlets (the IBOutlets must be nil or they won't be changed, that's the "rule" of loading XIBs into an owner object. It's ok that some IBOutlets are not nil, they just won't be changed when you load the XIB file, and usually that's what you want), and you've got your .xib file with objects that you want to load into the owner object. You call:

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

.. and voila! Now any nil IBOutlets in "theOwner" that are connected to objects in the MyXIBFileToLoad.xib have been set to the new objects loaded from the XIB file.

(also, this method returns an array of all objects unarchived from the xib. If you don't care about setting any owner's outlets, you can just search this list for your objects by class and by tag).

So that's the story, now go crazy with new ways to associate Objective-C classes with objects stored in XIB files!

like image 152
Bogatyr Avatar answered Nov 09 '22 23:11

Bogatyr