One xib File with Multiple "File's Owner"s
Asked Answered
P

3

23

I've got three different UITableViews, each in it's own view, accessed via tabs. All three tables would ideally share the same custom UITableViewCell class and .xib file.

I started with one table, setting the class of the .xib to my custom class and the File's Owner of the .xib to the table's parent UIViewController, which works great. All of the custom view-related code is in the cell's class (background images based on a property set by the controller, custom cell height based on the number of lines a label requires based on a cell property set by the controller, etc.).

The result is nice: the cell is responsible for all of the visual layout and responding to user actions on the cell's controls, while the view controller is responsible for creating the cells and setting their data.

Now that I need to reuse the cell in other tables, though, the fact that the custom cell's .xib has a single File's Owner is a problem. Rather than duplicating the .xib file, is there a simple way to allow multiple controllers to own it?

Poussette answered 1/5, 2011 at 15:28 Comment(3)
I guess I'm not following your problem 100%. Are you using UITableView's delegate method - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath?Nahama
@Nahama Yes. The problem is that the other view controllers don't have access to the .xib's controls/properties with another controller serving as the owner.Poussette
I have my custom cell's xib 'File's Owner' set to NSObject, and the 'Cell' to MyCustomTableViewCell.Nahama
A
40

A nib's File's Owner is not strictly enforced. Instead it is only used to determine available outlets and actions, and to set bindings within Interface Builder. You can load a nib with any object as its File's Owner regardless of the class set in the nib file. When a nib is loaded it will send messages to the File's Owner to re-establish bindings. If the actual File's Owner object does not recognize those selectors you will have triggered an "unrecognized selector" exception. This means that if your nib binds some UITableViewCell to the 'cell' outlet of its File's Owner then any object with a 'cell' property could load that nib. You just need to be careful not to use this behavior to send an unrecognized selector or unexpected outlet class.

In your case, consider creating a single UIViewController subclass to act as the File's Owner of your nib. Have each of your three existing controllers extend that view controller subclass. That way they can all inherit the same set of properties expected by the nib file and all safely load that nib while still defining their own custom behavior.

Authorize answered 1/5, 2011 at 19:50 Comment(4)
Ah, great idea. The core issue is that the other view controllers had no access to the instantiated cell's properties; this solves that nicely. Thanks.Poussette
I have been working on this for a while, and I thin you are very close to answering my question. Perhaps a little help? A schematic of how your suggestion would actually be used would be great. I've tried, and can't get three different sub-classes of UITableViewCell to share the same TVCell in an XIB.Referent
@Referent that you will not be able to do. The class of the view loaded from a nib file is defined by the nib itself. The answer above was in reference to different controller classes loading instances of the same UITableViewCell from a common nib file. That's different than attempting to load multiple subclasses of the class found in a nib out of the nib itself. You seem to have a different problem to solve which is probably worth opening a new question for.Authorize
It works! Awesome! But I'd better use word "subclass" or "inherit" instead of word "extend" in order to avoid misunderstanding.Diurnal
O
4

The checked answer to this question discusses two approaches to load custom table cells from nib files that do not require to set the File's Owner to your specific controller. These approaches let you reuse cells with different owners.

Organizer answered 1/5, 2011 at 16:17 Comment(1)
Thanks for pointing me to those, they're both good ways to structure things to work the way I'd like. Unfortunately both would require significant restructuring of other code, which I haven't time for now. I'm sure I'll pay for that choice later, though, a kind of code karma. :)Poussette
B
1

A "shared" super class as a file owner is not always a good solution. Remember that you can always load the xib in your view, and make connections without using outlet, for example:

UIView *aView = [[NSBundle mainBundle] loadNibNamed:@"MyXibFile" owner:self options:nil]
//Search subviews by tag. Obviously you need to set the tag on your view in MyXibFile
UILabel *aLabel = (UILabel*)[aView viewWithTag:996]; 
UILabel *aTextField = (UITextField*)[aView viewWithTag:997]; 
aTextField.delegate = self;
//etc...

I can't say that this is a clean solution, but in some cases could work better than inheritance .

Barrier answered 14/10, 2014 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.