tableView.tableHeaderView being set but not drawn - iphone

whenever I set my tableHeaderView I'm not seeing it in the Simulator.
If I add it as a subview, it ends up getting drawn underneath the section header. Any idea what I'm missing here?
I do have a XIB file. I didn't see any properties in IB to affect headerViews though.
- (void)viewDidLoad {
[super viewDidLoad];
MyTitleView *titleView = [[MyTitleView alloc] initWithFrame:CGRectMake(60,0,260,40)];
titleView.label.text = #"My Title";
self.navigationItem.titleView = titleView;
[titleView release];
StandardTableHeaderView *headerView = [[StandardTableHeaderView alloc] initWithFrame:CGRectMake(0,0,320,44)];
self.tableView.tableHeaderView = headerView;
// [self.view addSubview:self.tableView.tableHeaderView];
// [headerView release];
NSLog(#"Header: %#",self.tableView.tableHeaderView); //Logs ] Header: <StandardTableHeaderView: 0x5a508b0; frame = (0 0; 320 44); layer = <CALayer: 0x5a51130>>
Edit:
StandardTableHeaderView.m init method:
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.backgroundColor = [UIColor redColor];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(frame.origin.x,0,frame.size.width,frame.size.height)];
self.label.backgroundColor = [UIColor clearColor];
self.label.textColor = [UIColor whiteColor];
self.label.font = [UIFont fontWithName:#"Helvetica" size:16];
[self addSubview:self.label];
}
return self;
}

Note! If you expect the table view to set the frame of the header view for you you're mistaken and will get very weird results.
I had mine set to CGRectZero thinking it'd solve itself, but the thing wouldn't appear and when it did, it would appear tucked in under the navbar or sticking down into the first cell and such.

First of all your code looks fine.
2 possible problems:
self.tableView is not set
tableHeaderView is overridden after viewDidLoad

I was having the same problem and noticed that any tableViewHeader that I defined in my NIB would not appear if I initialized my tableview by invoking:
- (id)initWithStyle:(UITableViewStyle)style
But it magically appeared without effort when I initialized my tableview by using:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
Weird.

I tried to put the setup of tableHeaderView in ViewDidLoad and loadView methods - it didn't work: part of the view was white, not visible completely. Then I tried to put it to ViewDidAppear and it worked:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self setupTableHeaderView];
}

Just came across the same problem where I had it in viewDidLoad() it worked in the simulator for iPhone 11 Pro but not for iPhone 8. Moving it to viewDidAppear() solved the problem, but I ended up moving it to viewDidLayoutSubviews() which I felt was the most appropriate place for it - works perfectly in the simulator across all iPhone models.
override func viewDidLayoutSubviews() {
let headerView = Bundle.main.loadNibNamed("HeaderView", owner: self, options: nil)?.first as? UIView
headerView!.frame = CGRect(x: 0, y: 0, width: table_view!.frame.width, height: 160.0)
tableView!.tableHeaderView = headerView
}

I had a problem where i was putting a view inside a tableviewcontroller as a header and it would not show up when i ran the app, the problem was i added the header when there were no prototype cells. if you add at least one prototype cell, then add the header above it, then delete the cell (if need be), it registered it as a headerview properly

when you UIView inside the UITableView in the storyboard and you try to set tableView.tableHeaderView = YOUR_VIEW, it won't work. You have to first drag-drop that view outside view controller create its outlet and then set
tableView.tableHeaderView = YOUR_VIEW

Drawing upon the key clue from Kalle I've added this
open var intrinsicContentheight: CGFloat
{
achievementLabel.sizeToFit()
let labelSize = achievementLabel.bounds.size
return labelSize.height + 13 + .verticalMargin
}
abomination to the class that defines the header view.
If you don't have dynamic type you'd have a simpler method yet.
Here is the usage in the view controller that sets up the tableheaderview
with the instance of this class
loanApplicationStepsView.bounds.size.height = loanApplicationStepsView.intrinsicContentheight
cause as Kalle have stated just because there is no func tableViewHeightForHeader(_ tableView: UITableView) -> CGFloat in uitableviewdelegate doesn't mean you don't have to do the dance to compute it
the width get set automatically by uikit

Try setting UITableViewDelegate in your header and place the following code in your .m file.
#pragma mark UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 44.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
StandardTableHeaderView *headerView = [[StandardTableHeaderView alloc] initWithFrame:CGRectMake(0,0,320,44)];
return headerView;
}

Related

UICollectionView in UITableViewCell - touches only received in a portion of view

I'm having an issue receiving touches in UICollectionViews contained within UITableViewCells. The desired effect is a UITableView with n rows of horizontally scrolling UICollectionViews. The view is displaying correctly but the collection views only receive touches in the top 44px. I imagine that the table view is still in the process of initialization when the collection views are created and that the collection views are using UITableView's default cell height when setting up their gesture recognizers. Relevant code is below.
In my UITableViewCell subclass, I create a container view for the UICollectionView:
- (void)layoutSubviews
{
if (!_collectionViewContainer) {
_collectionViewContainer = [[CVTCollectionViewContainer alloc] init];
_collectionViewContainer.frame = self.bounds;
[self.contentView addSubview:_collectionViewContainer];
};
}
In my container view, I instantiate a UICollectionView:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
if (!self.collectionView) {
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:flowLayout];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.backgroundColor = [UIColor clearColor];
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flowLayout.itemSize = CGSizeMake(130.0, 130.0);
[_collectionView registerClass:[CVTCollectionViewCell class] forCellWithReuseIdentifier:#"Collection view cell"];
[self addSubview:self.collectionView];
}
}
There's nothing interesting in my UITableViewController, just that I return 200 in tableView:heightForRowAtIndexPath:
It occurred to me that the layoutSubviews method of my UITableViewCell subclass may be the wrong place for initialization of the 'container' view for my UICollectionView. But, when I NSLog(#"cell: %#", self); in layoutSubviews, the cell's frame shows the desired height (200). Still, I have a feeling that I am doing my setup for the collection view too early, but I can't think of where else I might perform this work.
So, the gist: how can I add a UICollectionView to a UITableViewCell and make sure that the UICollectionView's gesture recognizers respond in the entirety of the collection view, rather than just the top 44 px?
Thanks in advance, as always.
Bit of a facepalm here, I was using a UITableViewController that was created in storyboard but mostly configured in code. In storyboard, I had not set the row height of the table view, so it was still at the default 44 px. Of course, the table view looked at IB for its initial config so, although tableView:heightForRowAtIndexPath: was being called and the cells were displaying correctly, the initial height set in IB was affecting how the cell's subviews were created.

scrollsToTop not working with UIViewController containment

Using SDK 6.1, Xcode 4.6.1, I make a new project Master-Detail iOS App, ARC, no storyboards.
Then in the DetailViewController, in the viewDidLoad I add two UITableViews contained in UIViewControllers and make sure the second one is hidden like this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIViewController *lViewController1 = [[UIViewController alloc] init];
UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView1.scrollsToTop = YES;
[lViewController1.view addSubview: lTableView1];
lTableView1.dataSource = self;
[self.view addSubview: lViewController1.view];
[self addChildViewController: lViewController1];
UIViewController *lViewController2 = [[UIViewController alloc] init];
UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView2.scrollsToTop = YES;
[lViewController2.view addSubview: lTableView2];
lTableView2.dataSource = self;
[self.view addSubview: lViewController2.view];
[self addChildViewController: lViewController2];
// now hide the view in view controller 2
lViewController2.view.hidden = YES;
}
(I make sure the DetailViewController is a datasource that returns 100 rows of UITableViewCells with the textLabel.text set to #"hello")
The presence of the second view controller makes that scrollsToTop (tapping on the status bar) does not work anymore. If I do not use UIViewController containment and just add two UITableViews and set the second one to be hidden, scrollsToTop does work.
What am I doing wrong?
scrollsToTop only works on a single visible view. From the documentation:
This gesture works on a single visible scroll view; if there are multiple scroll views (for example, a date picker) with this property set, or if the delegate returns NO in scrollViewShouldScrollToTop:, UIScrollView ignores the request. After the scroll view scrolls to the top of the content view, it sends the delegate a scrollViewDidScrollToTop: message.
You could try calling [tableView setContentOffset:CGPointZero animated:YES] on each of your table (or scroll) views manually instead. To do this, implement the scrollViewShouldScrollToTop: method in the UIScrollViewDelegate protocol:
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
[lTableView1 setContentOffset:CGPointZero animated:YES];
[lTableView2 setContentOffset:CGPointZero animated:YES];
return NO;
}
You can only set 1 ScrollView per ViewController with property .scrollsToTop = YES.
If you set 2 scrollview.scrollsTopTop = YES, it will simply stop functioning.
ie: your sample project (DetailViewController.m) update following lines,
line48: lTableView1.scrollsToTop = YES;
line56: lTableView2.scrollsToTop = NO;
then, scrollsToTop works correctly. If there are more than 1 scrollview you wish to concurrently setScrollsToTop, keep digging around. good luck!
I am currently experimenting with your project. When
lViewController2.view.hidden = YES;
is replaced with
lTableView2.hidden = YES;
then the scrolling works, even with controller containment.
I tried to insert a view between the controller's view and the table and then hide this view, but the table was not scrolling.
I tried to hide the controller by experimenting with shouldAutomaticallyForwardAppearanceMethods but the table was not scrolling.
Result: From my experiments, only one scroll view must be visible in the view hierarchy and the hidden property of the parent views is not checked out. hidden must be set to NO on all other scroll views, not their parent views.
After testing several options and various hits and try I finally settled to one final solution, i.e. setBounds: of scrollView (that is tableView in your case) and it works good. You'll have to put extra effort for animation although.
CGRect frame = scrollView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
[scrollView setBounds:frame];
By the way in your case, try returning YES to
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;
Although if not defined, assumes YES.
I have used this and now it works fine.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIViewController *lViewController1 = [[UIViewController alloc] init];
UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView1.scrollsToTop = YES;
[lViewController1.view addSubview: lTableView1];
lTableView1.dataSource = self;
[self.view addSubview: lViewController1.view];
[self addChildViewController: lViewController1];
lTableView1.tag=1;
UIViewController *lViewController2 = [[UIViewController alloc] init];
UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView2.scrollsToTop = NO;
[lViewController2.view addSubview: lTableView2];
lTableView2.dataSource = self;
[self.view addSubview: lViewController2.view];
[self addChildViewController: lViewController2];
lTableView2.tag=2;
// now hide the view in view controller 2
lViewController2.view.hidden = YES;
}
- (NSUInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSUInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const kCellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"hello %d %d",indexPath.row, tableView.tag];
return cell;
}

iAd below UITableViewController inside UINavigationController

I'm building an app for a blog site.
I have a UINavigationController with a UITableViewController as it's root view.
I laid this out in a storyboard no problem, but I'm trying to drag an iAd view to the bottom of the screen and xcode will not let me add it.
It looks like I have to switch from a subclass of UITableViewController to a subclass of UIViewController, and just put my delegate and datasource methods in my subclassed UIViewController.
This seems wrong to me. I'm just trying to end up with a UITableView of article headlines, with a navbar up top, and an iAd at the bottom...
Advice? Suggestions?
Thanks in advance.
One of the easiest ways to accomplish this is using the UITableView's tableFooterView property. Yes, I know the footer stays at the bottom of the table, but it doesn't have to. You can set its frame within the table. Add the iAd as the footer like so:
self.tableView.tableFooterView = iAd;
Then, to adjust the frame of the iAd as the table scrolls, implement the UIScrollView delegate method: (This is possible because UITableView is a subclass of UIScrollView)
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGRect iAdFrame = iAd.frame;
CGFloat newOriginY = table.contentOffset.y + table.frame.size.height - iAdFrame.size.height;
CGRect newIAdFrame = CGRectMake(iAdFrame.origin.x, newOriginY, iAdFrame.size.width, iAdFrame.size.height);
iAd.frame = newIAdFrame;
}
You can see that the implementation is easy enough. We simply use the contentOffset y to determine how far down the frame of the iAd should be.
I tried to use the example above by NJones with adjusting the position of the tableFooterView, but I found out it was hard to manage it when reloading the data or refreshing the table.
Then I found out that this could be done by adding the iAd banner to the superview of the tableViewController's view.
self.bannerViewController = [[BannerViewController alloc] init];
[self.bannerViewController.view setHidden:YES];
[self.bannerViewController.view setFrame:CGRectMake(0, self.view.superview.frame.size.height - self.tabBarController.tabBar.frame.size.height - 50, 320, 50)];
[self.view.superview addSubview:self.bannerViewController.view];
[self.bannerViewController loadBanner];
When the banner is loaded I create a tableFooterView to make space for the last cell in the tableViewController
-(void)bannerDidLoad{
[self.bannerViewController.view setHidden:NO];
self.tableView.tableFooterView = [[UIView alloc];
initWithFrame:self.bannerViewController.view.frame];
}
I had to make some changes to the solution posted by NJones, since there was a problem with the ad not being displayed on top of all other cells/views.
First make sure your tableViewController is a AdBannerViewDelegate:
#interface MyTableViewController () <ADBannerViewDelegate>
Adding the AdBanner to the tableviewcontroller:
- (void)viewDidLoad {
[super viewDidLoad];
...
ADBannerView *adBanner = [[ADBannerView alloc]initWithAdType:ADAdTypeBanner];
adBanner.delegate = self;
self.tableView.tableFooterView = adBanner;
}
The code to position the ad banner is taken from NJones, I only added the last line to bring the ad banner to the front:
-(void)positionAdBanner {
ADBannerView *adBanner = (ADBannerView *) self.tableView.tableFooterView;
if (adBanner) {
CGRect iAdFrame = adBanner.frame;
CGFloat newOriginY = self.tableView.contentOffset.y + self.tableView.frame.size.height - iAdFrame.size.height;
CGRect newIAdFrame = CGRectMake(iAdFrame.origin.x, newOriginY, iAdFrame.size.width, iAdFrame.size.height);
adBanner.frame = newIAdFrame;
[self.tableView bringSubviewToFront:adBanner];
}
}
This function gets called whenever the view is going to layout its subviews (so you only need it here, no need to check for scrolling, etc):
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
[self positionAdBanner];
}
You also should handle the ADBannerViewDelegate methods:
-(void)bannerViewDidLoadAd:(ADBannerView *)banner
{
banner.hidden = NO;
[self positionAdBanner];
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
banner.hidden = YES;
}

UIScrollview calling superviews layoutSubviews when scrolling?

I added a UITableView as a subview to a custom UIView class I'm working on. However I noticed that whenever I scroll the table it calls my classes layoutSubviews. I'm pretty sure its the UIScrollview that the table is inheriting from which is actually doing this but wanted to know if there is a way to disable this functionality and if not why is it happening? I don't understand why when you scroll a scrollview it needs its superview to layout its subviews.
Code:
#implementation CustomView
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.clipsToBounds = YES;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 15.0, 436.0, 132.0) style:UITableViewStylePlain];
tableView.dataSource = self;
tableView.delegate = self;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.backgroundColor = [UIColor clearColor];
tableView.showsVerticalScrollIndicator = NO;
tableView.contentInset = UIEdgeInsetsMake(kRowHeight, 0.0, kRowHeight, 0.0);
tableView.tag = componentIndex;
[self addSubview:tableView];
[tableView release];
}
return self;
}
- (void)layoutSubviews {
// This is called everytime I scroll the tableview
}
#end
Yes, a UIScrollView does call layoutsubviews whenever it scrolls. I could've sworn this was stated in the documentation somewhere, but I guess not.
Anyways, the prevailing idea for this is that a UIScrollView should layout its stuff so that views that currently can't be seen shouldn't be laid out. As users scroll in the scroll view, it should add and remove subviews as necessary. I'm guessing this is what TableViews use to enqueue table cells that get hidden.
Is there any reason why you would care if layoutsubviews gets called or not?
UITableView at least does appear to layout its superview. This behavior can be problematic when you have a layoutSubviews method that might be expensive (e.g. if you call some JavaScript).
The quick fix is add an intermediary subview that prevents the scroll view from laying out your superview. Instead, it will layout the intermediate subview.
This could be somewhat imperfect but it should work for most cases:
Assume UIView * intermediateView is defined as an instance variable:
-(id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
if (self)
{
UIScrollView * theScrollView; // = your scroll view or table view
intermediateView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
// Ensures your intermediate view will resize its subviews.
intermediateView.autoresizesSubviews = YES;
// Ensure when the intermediate view is resized that the scroll view
// is given identical height and width.
theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[intermediateView addSubview: theScrollView];
// Ensure the frame of the scroll view is exactly the bounds of your
// intermediate view.
theScrollView.frame = bottomContainerView.bounds;
[self addSubview: intermediateView];
}
return self;
}
-(void) layoutSubviews
{
intermediateView.frame = CGRectMake(0, 50, 42, 42); // replace with your logic
}
Not sure i understand your issue correctly but when you scroll a tableview it removes the cells not shown from the memory and loads them again when they are scrolled back into visibility (cells are allocated on demand, only the visible ones) , in effect doing what you seem to be describing.

iPhone UITableView with a header area

I have a view that was created with all of the default UITableView stuff, but now I need to add a header area above where the UITableView is (so the UITableView will scroll normally, but the top 100px of the screen or so will have static header content). I don't see where I can resize the UITableView in IB, and am not sure how to do this.
Does anyone know?
You can use UITableViewDelegate methods to create a custom header view for a table and specify the height, namely tableView:viewForHeaderInSection: and tableView:heightForHeaderInSection:. You can add whatever you like to the view. Here's an example that adds a right aligned UILabel:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width,30)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, headerView.frame.size.width-120.0, headerView.frame.size.height)];
headerLabel.textAlignment = NSTextAlignmentRight;
headerLabel.text = [titleArray objectAtIndex:section];
headerLabel.backgroundColor = [UIColor clearColor];
[headerView addSubview:headerLabel];
return headerView;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30.0;
}
Why don't you use the UITableView provided header?. As follow:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"My Title";
}
Additionally you may resize your table view in IB by dragging the borders.
When you add a UIView or one of its subclasses onto the UITableView using IB (just drag a UIView and drop it onto the UPPER part of UITableView of yours), it automatically adds that UIView component and makes it the "tableHeader" component.
Each UITableView has one tableHeader and one tableFooter component reserved...
This way the new view would be a part of the UITable, and scroll with it or appear/disappear or whatever you do to the table. You can change its hidden property if you need conditional behavior.
On the other hand, if you want the header view stay put, as the table scrolls, then it is better to make the table smaller and put the header above it as suggested in other answers...
I finally solved this problem the right way without changing the base class. The one answer to add the view to the parent nav controller is nice but the transitions look horrible.
The fix is actually easy. The trick is to create custom setter and getter for self.tableView property. Then, in loadView, you replace the view with a fresh UIView and add the tableView to it. Then you're free to add subviews around the tableView. Here's how it's done:
In header:
#interface CustomTableViewController : UITableViewController
{
UITableView *tableView;
}
In .m:
- (UITableView*)tableView
{
return tableView;
}
- (void)setTableView:(UITableView *)newTableView
{
if ( newTableView != tableView )
{
[tableView release];
tableView = [newTableView retain];
}
}
- (void)loadView {
[super loadView];
//save current tableview, then replace view with a regular uiview
self.tableView = (UITableView*)self.view;
self.view = [[UIView alloc] initWithFrame:self.tableView.frame];
[self.view addSubview:self.tableView];
//code below adds some custom stuff above the table
UIView *customHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
customHeader.backgroundColor = [UIColor redColor];
[self.view addSubview:customHeader];
[customHeader release];
self.tableView.frame = CGRectMake(0, customHeader.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - customHeader.frame.size.height);
}
- (void)viewDidUnload
{
self.tableView = nil;
[super viewDidUnload];
}
Enjoy!
You will have to embed the UITableView in a UIView alongwith another view (which you are referring to as header section).
So, the UIView will have 2 subviews. The header view followed by the table view.
UIView(parent)
UIView (header)
UITableView (table)
Hope this helps.
I like the answer from noodl_es (upvoted), because it provides the functionality and behavior you want, yet you don't have to worry about resizing the UITableView: that is handled for you automatically. However, the solution is best suitable only if the header information pertains specifically to the first section of the table (or if the table has only one section). If the table has more than one section, then the header of the second section will push away the header of the first section when scrolled up, and therefore the header view will not appear to pertain to the whole table.
Found a solution at iphonedevsdk
Instead of doing this:
[tableViewController.view addSubview:viewSubclass];
do this
[tableViewController.navigationController.view addSubview:viewSubclass];
Suppose to have your UITableViewController
#interface MXMTableViewController : UITableViewController <UITableViewDelegate,UIScrollViewDelegate> {
/// your table view interface here
}
and a xib with you simple UITableView defined yet in it, you can do as Mihir says overriding the loadView method like this:
- (void)loadView {
[super loadView];
UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view = mainView;
[mainView release];
// Add Header View
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 36)];
headerView.backgroundColor = [UIColor redColor];
[self.view addSubview:headerView];
// now, move your table view down. Check you nib to choose
// the right Y-axis offset
CGRect f = tableView.frame;
f.origin.y += headerView.frame.size.height/2;
tableView.frame = f;
// Add the table view to the container view
[self.view addSubview:self.tableView];
// Add footer
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.frame.size.height, 320, 125)];
footerView.backgroundColor = [UIColor redColor];
[self.view addSubview:footerView];
[footerView release];
[headerView release];
}
...and that's it. You have a UITableView with fixed header and footer.
PS. You may now use your xib custom views as the header and footer's views.