Reputation: 4264
I have a UITableView in grouped style in my iPhone app. Now I want to customize the section headers with an Image, a label and an activity indicator.
To do this I created a new UIViewController subclass and a XIB file. I added the UIImageView, UILabel and UIActivityIndicatorView as IBOutlet properties to the ViewController and wired them to controls I put into the XIB in Interface Builder.
In the class where my UITableView is made I setup the section headers (two, both instances of the ViewController defined above) and set their properties (image and text). Then I return the ViewControllers view in the tableView delegate:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (section == 0) {
return [favoritesSectionHead view];
} else {
return [serverlistSectionHead view];
}
}
This displays the view as I defined it in Interface Builder, without the custom image and text. I know why this happens (the view of a ViewController is created when first needed, in my code this is when I return it in the viewForHeaderInSection method --> when I try to setup the custom values the view is still nil) but I don't know how to fix this.
Can you help me? What do I have to do to init the view before my returns? The UITableView docs tell me not to call "loadView" manually ...
Thanks in advance, Mark.
Upvotes: 1
Views: 6566
Reputation: 1134
I had the same problem with the view = (null). It is all about the "Delegates". My tableView was working fine, and all my UITableView Delegate methods were properly working, however the viewForHeaderInSection: would not implement.
I discovered that Xcode was letting me build with a weak-linked reference with the TableView, which was not sufficient for the "viewForHeaderInSection:" method.
I also discovered that Xcode will easily push a "Coded" custom view from within the viewForHeaderInSection: method, with this same weak reference, but using IB, the link has to be more established. Takes a little more work, but offers a much better experience once you get it down to build much more complicated objects.
I used: NSLog([NSString stringWithFormat:@"%@", self.headerView]);
to verify that the view was outputting as (null).
The viewForHeaderInSection: method is called first, if nil or null, the tableView calls the "titleForHeaderInSection:" next. (you can also use this to your advantage).
Make sure your setup is correct and makes sense on how the objects work with one another.
Sample Steps that worked for me:
(.h)
Properly setup a viewController, and declare the tableView delegation methods. I was using the generic UITableViewController, didn't work for me inside complex TabBar, with UINavigationControllers.
@interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate, UIAccelerometerDelegate> {
Create all the IBOutlets that will be on your view:
IBOutlet UITableView *myTableView;
IBOutlet UIView *yourCustomHeaderView;
IBOutlet UIImageView *yourImageOnCustomView;
Assign Memory Allocation Assignment:
@property(nonatomic,retain) IBOutlet UITableView *yourTableView;
@property(nonatomic,retain) IBOutlet UIImageView *yourCustomHeaderView;
@property(nonatomic,retain) IBOutlet UIImageView *yourImageOnCustomView;
(.m)
Synthesize your Variables:
@synthesize yourTableView, yourCustomHeaderView, yourImageOnCustomView;
Implement all your standard TableView delegate required methods, plus:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
//Intialize the header View to present:
UIView *headerView;
//Display Section Headers for rows:
if (section == 0) {headerStatBar = self.yourCustomSectionHeaderView1;}
if (section == 1) {headerView = self.yourCustomSectionHeaderView1;}
if (section == 1) {headerView = self.yourCustomSectionHeaderView1;}
//Return the view to the Table:
return headerView;
}
Make all your Connections in IB, easiest way:
Now that the connections are made, you have "FULL" control over aspect of each item, by setting any property of that item, such as self.yourCustomHeaderView.background = [UIColor redColor]; etc....
** Make sure you Drag from the "TableView" to the "File's Owner" to set the table's (delegate) and (datasource) back to the file's owner; which happens to be where all your tableView delegate methods are!
This is just the simplest of steps, you can make the view as complex as you need it, one of my viewForHeaderInSection: views has 40+ IBoutets for all the views, which include buttons, images, labels, other views, etc...
Upvotes: 1
Reputation: 11
Your view hasn't loaded yet. That's why it's nil. Do your modification code in ViewDidLoad.
I had a similar problem where I was trying to edit label values after I'd initialized the header, but I but the labels were all nil. I solved the problem by calling the label modification code from the viewDidLoad method of the header view controller.
Upvotes: 1
Reputation: 4264
I had to add a NSString property to my section view controller. In the viewDidLoad I assigned this string to the UILabel text property, now it is working.
Upvotes: 0