New Method of Getting Items out of Nib Files.
Example in answer below.
This new Answer is the latest change in this project and Question
I want to create a UIView subclass and I want to create an Interface builder file for the UIView. How would I connect the files owner to itself. I want to be able to Design the view and have it create the connections but I dont have a need for a view controller.
Other than loading the nib into an array can I use the nib file as a connector to the view itself ?
I hope i am Asking this properly. I will elaborate tho.
Creating a UIViewController I am given the choice to create an xib file for it. At which time i can add the UIViews to the xib and those connections would be made. However the files owner does not appear to have a UI Editor associated to it so I want to create a UIView that will become a sub view in another view. I dont really want to create it with code because Its a pain to layout the items manually. So I want to use the same construct to create a small uiview to put into another
EDIT:
I Edited this again when I found another even better way to load nib classes. I figured some stack overflow users would want to see this.
I wanted to find an elegant way to load a UIView from a nib. and with some info from stack overflow user PeyloW I have managed to do just that.
I am going to post my results as the information will lead to a solution but this solution feels exceptionally elegant to me.
- First of all, I created a Xib File named "TableViewCells.xib"
(Name Matches the Class Name therefore [[self class] description] == "TableViewCells") - Next I created the Classes that I am using for the views in the Nib. Classes dont matter, Just Make sure the "Custom Class" is selected for the Class Objects in interface builder
- Finally I created the Class "TableViewCells" to match the xib filename
My new Header File.
(Each of the header files imported associate to the items in the single xib file.)
#import <Foundation/Foundation.h>
#import "TitleCell.h"
#import "ToggleCell.h"
#import "ButtonCell.h"
#import "TextCell.h"
@interface TableViewCells : NSObject {
UINib *uiNibHolder;
}
@property (nonatomic, readonly) NSArray *nibArray;
// These are the classes that will be loadable.
- (TitleCell*) titleCell;
- (ToggleCell*) toggleCell;
- (ButtonCell*) buttonCell;
- (TextCell*) textCell;
- (id) loadViewByClass: (id) viewClass;
@end
and the Class file.
loadViewByClass: is the method that finds the item in the nib file.
the convenience accessors have the correct type for the class objects to be instantiated into.
NOTE: I would Not Recommend loading a Bunch of Views into this, the more views you load the more you have to create when you load the nib file.
#import "TableViewCells.h"
@implementation TableViewCells
@synthesize nibArray;
- (void) unloadProperties{
[uiNibHolder release];
}
- (NSArray *)nibArray{
return [uiNibHolder instantiateWithOwner:nil options:nil];
}
- (id) init{
if ((self = [super init]))
{
// Im using the class name for the Xib file.
// This means it will look in TableViewCells.xib
// You can change the class name, or pass a Nib name to this class
uiNibHolder = [[UINib nibWithNibName:[[self class] description] bundle: [NSBundle mainBundle]] retain];
}
return self;
}
- (TitleCell *)titleCell{
return [self loadViewByClass:[TitleCell class]];
}
- (ToggleCell *)toggleCell{
return [self loadViewByClass:[ToggleCell class]];
}
- (ButtonCell *)buttonCell{
return [self loadViewByClass:[ButtonCell class]];
}
- (TextCell *)textCell{
return [self loadViewByClass:[TextCell class]];
}
- (id)loadViewByClass:(Class)viewClass{
for (id item in self.nibArray)
{
if ([item isKindOfClass:viewClass])
{
return item;
}
}
return nil;
}
- (void)dealloc{
[self performSelector:@selector(unloadProperties)];
[super dealloc];
}
@end
Being able to load by class is incredibly nice. And if the class is not in the xib file it will return nil.
This could be adapted to use multiple nib files depending on the type of views you were loading. Using a lazy load property technique you could load those nibs only when needed leaving the memory footprint small and still allowing you to get the classes loaded through one convenient class loader.
As a demonstration I used a TableView to load a handfull of views
@synthesize tableViewCellLoader = _tableViewCellLoader;
- (TableViewCells *)tableViewCellLoader{
if (_tableViewCellLoader == nil){
_tableViewCellLoader = [[TableViewCells alloc] init];
}
return _tableViewCellLoader;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
switch (indexPath.row) {
case 0:
return self.tableViewCellLoader.toggleCell;
break;
case 1:
return self.tableViewCellLoader.textCell;
break;
case 2:
return self.tableViewCellLoader.titleCell;
break;
case 3:
return self.tableViewCellLoader.buttonCell;
break;
}
return nil;
}
As you can see I lazy loaded my TableViewCellLoader and if I wanted to I could make the TableViewCells class lazy load UINib objects only when their classes were called.
I love convenience in code.
And Still, Thanks again PeyloW.