Reputation: 563
I want to create a section header that loads a nib file and sets that as the header UIView. This nib file will also have an associated class where the outlets and actions are connected to so I want to load that class with the nib like normal.
I've scoured the web and found several similar answers but I can't get any to work for me. After playing around for a few days I managed to get the view to show correctly but it doesn't do anything despite adding connections and telling the text to show differently.
For example it should clear the section title text if it's init with nil and it does that yet it still shows the same text, attempts to change it doesn't reflect either and any connections made with the button aren't triggered.
Here is my view controller for the view
@interface ADUNewRowHeaderViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *sectionTitleField;
@property (strong, nonatomic) IBOutlet UIButton *addRowBtn;
@property(strong,nonatomic) NSString* sectionTitle;
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
title:(NSString*) titleOrNil;
@end
and here is the implementation
@implementation ADUNewRowHeaderViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil title:(NSString *)titleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
if(titleOrNil != nil)
{
[self setSectionTitle:titleOrNil];
}
else
{
[self setSectionTitle:@""];
}
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setSectionTitle:(NSString *)sectionTitle
{
_sectionTitle = sectionTitle;
[[self sectionTitleField] setText:sectionTitle];
}
@end
in the actual table view controller it's listed as
@property(nonatomic, strong) ADUNewRowHeaderViewController* secHeader;
and in the implementation file under viewDidLoad as
[self setSecHeader:[[ADUNewRowHeaderViewController alloc] initWithNibName:nil bundle:nil title:nil]];
[[[self secHeader] addRowBtn] addTarget:self action:@selector(addNewRow:) forControlEvents:UIControlEventTouchUpInside];
and
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [[self secHeader] view];
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return [[self secHeader] view].bounds.size.height;
}
this is the method declaration for the action
- (IBAction)addNewRow:(id)sender;
Upvotes: 3
Views: 2830
Reputation: 22946
You should make a UIView
, instead of a UIViewController
, subclass. The .m
would contain:
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self setUp];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self setUp];
}
- (void)setUp
{
[[NSBundle mainBundle] loadNibNamed:@"YourNibName" owner:self options:nil];
CGRect frame = self.frame;
self.view.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
[self addSubview:self.view];
... do other initialisations here ...
}
And the .h
:
@interface ADUNewRowHeaderView : UIView
@property (nonatomic, strong) IBOutlet UIView* view;
Then in the XIB: Make File's Owner of class ADUNewRowHeaderView
, as usual. And connect the XIB's top-level View's Referencing Outlet to the view
property above (i.e. in File's Owner).
You then have a UIView subclass you can place on another XIB (as a UIView which for which you set the Class to ADUNewRowHeaderView), or instantiate in code and add as subview.
(Alternatively you could create the UIView and it's subviews (buttons, labels, ...) in code; then you would not need a XIB. But this only works of course if the UIView is simple and has little own logic, and few UI elements that are easy to layout in code.)
Upvotes: 1