<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jumping Through Hoops &#187; howto</title>
	<atom:link href="http://blog.jameshiggs.com/tags/howto/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jameshiggs.com</link>
	<description>James Higgs&#039;s Blog</description>
	<lastBuildDate>Sun, 04 Sep 2011 12:46:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>iPhone: how to create a transparent table header</title>
		<link>http://blog.jameshiggs.com/2009/03/01/transparent-table-header-uitableview/</link>
		<comments>http://blog.jameshiggs.com/2009/03/01/transparent-table-header-uitableview/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 13:54:30 +0000</pubDate>
		<dc:creator>higgis</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[cocoa touch]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://blog.jameshiggs.com/?p=176</guid>
		<description><![CDATA[A couple of weeks ago I was wondering how you created a transparent header for a table view on the iPhone like the one that&#8217;s in the built in contacts app detail view. Here&#8217;s a video of the contacts app so that you can see what I&#8217;m trying to achieve: Initially, I thought that the [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago <a href="http://twitter.com/higgis/status/1224333646">I was wondering</a> how you created a transparent header for a table view on the iPhone like the one that&#8217;s in the built in contacts app detail view. Here&#8217;s a video of the contacts app so that you can see what I&#8217;m trying to achieve:</p>
<p><object width="193" height="371"><param name="movie" value="http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/jingswfplayer.swf"></param><param name="quality" value="high"></param><param name="bgcolor" value="#FFFFFF"></param><param name="flashVars" value="thumb=http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/FirstFrame.jpg&#038;width=386&#038;height=742&#038;content=http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/00000004.swf"></param><param name="allowFullScreen" value="true"></param><param name="scale" value="showall"></param><param name="allowScriptAccess" value="always"></param><param name="base" value="http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/"></param>  <embed src="http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="193" height="371" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/FirstFrame.jpg&#038;width=386&#038;height=742&#038;content=http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/00000004.swf" allowFullScreen="true" base="http://content.screencast.com/users/higgis/folders/Jing/media/490cd6ed-86ba-4244-a744-ae912e085f72/" scale="showall"></embed></object></p>
<p>Initially, I thought that the way to do this was to add an additional section to the table and add a custom cell to it. That kind of works, but is quite hard work. I think I&#8217;ve found a better and simpler way &#8211; by using the <code>tableView:viewForHeaderInSection</code> method on <code>UITableViewDelegate</code>. </p>
<p>To start with, we need to create a basic view-based Cocoa Touch app in XCode. I&#8217;ve called mine ContactStylee. I&#8217;ve <a href="http://blog.jameshiggs.com/wp-content/media/ContactStylee.zip">zipped up the completed XCode project for you</a> so that you can follow along.</p>
<p><span id="more-176"></span></p>
<p>Once we&#8217;ve got the basic project template, we need to implement the <code>UITableViewDataSource</code> in our <code>ContactStyleeViewController</code>. As usual, this consists of implementing <code>tableView:numberOfRowsInSection</code> and <code>tableView:cellForRowAtIndexPath</code>. I also create a simple <code>NSArray</code> to hold some sample data in the <code>viewDidLoad</code> method. Here&#8217;s the interface file:</p>
<pre>
@interface ContactStyleeViewController : UIViewController
	&lt;UITableViewDataSource, UITableViewDelegate&gt; {

	NSArray *data;
	ContactStyleeAppDelegate *appDelegate;
}

@property (nonatomic, retain) NSArray *data;

@end
</pre>
<p>And the implementation: </p>
<pre>
@implementation ContactStyleeViewController

@synthesize data;

- (void)viewDidLoad {
   	[super viewDidLoad];
	self.data = [NSArray arrayWithObjects:
		@"First", @"Second", @"Third", @"Fourth", nil];
}

- (NSInteger)tableView:(UITableView *)tableView
	numberOfRowsInSection:(NSInteger)section {

	return [self.data count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
	cellForRowAtIndexPath:(NSIndexPath *)indexPath {

	UITableViewCell *cell = [tableView
		dequeueReusableCellWithIdentifier:@"normalcell"];
	if(nil == cell) {
		cell = [[[UITableViewCell alloc]
			initWithFrame:CGRectZero
			reuseIdentifier:@"normalcell"] autorelease];
	}
	cell.text = [self.data objectAtIndex:indexPath.row];
	return cell;
}

- (void)dealloc {
	[data release];
	[super dealloc];
}
@end</pre>
<p>All pretty standard stuff. In the NIB, I&#8217;ve set the table to have the &#8220;Grouped&#8221; style. Here&#8217;s what that looks like when we run it in the simulator:</p>
<p><img src="http://blog.jameshiggs.com/wp-content/uploads/2009/02/conventional-grouped-table.png" alt="Conventional Grouped Table" border="0" width="212" height="394" /></p>
<p>So now we need to create the header view. I did this by adding a new View NIB to the project, calling it <code>TableHeader</code>. I then created a new view controller class, called <code>TableHeaderViewController</code>, and then set the class for the File&#8217;s Owner in the TableHeader.xib file to the new controller class. You need to remember to tell the File&#8217;s Owner about the view. I added an image and a couple of labels. For the purposes of this demo project, that&#8217;s all that&#8217;s needed in the header view: we won&#8217;t bother hooking it up to the data source for now.</p>
<p>To be able to reference the view from the <code>ContactStyleeViewController</code>, I added a new view controller to MainWindow.xib and made its class <code>TableHeaderViewController</code>, and we tell it to load the view from <code>TableHeader.xib</code>. I then added an <code>IBOutlet</code> of type <code>TableHeaderViewController</code> to <code>ContactStyleeAppDelegate</code>. This means that I can load that controller&#8217;s view from the app delegate.</p>
<p>Now that we&#8217;ve got the controller outlet and property in our app delegate, we need to hook that up in IB. So we make the new view controller that we just added to <code>MainWindow.xib</code> point to the new <code>IBOutlet</code> that we just added in the <span>ContactStyleeAppDelegate</code>. Here's how the app delegate interface file looks now:</p>
<pre>#import &lt;UIKit/UIKit.h&gt;

@class ContactStyleeViewController;
@class TableHeaderViewController;

@interface ContactStyleeAppDelegate : NSObject &lt;UIApplicationDelegate&gt; {
	UIWindow *window;
	ContactStyleeViewController *viewController;
	TableHeaderViewController *headerViewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet ContactStyleeViewController *viewController;
@property (nonatomic, retain) IBOutlet TableHeaderViewController *headerViewController;

@end</pre>
<p>Now we need a way for the <code>ContactStyleeViewController</code> to access our <code>TableHeaderViewController</code>. To do this, we add an <code>IBOutlet</code> of type <span>ContactSyleeAppDelegate</span> to our <code>ContactStyleeViewController</code> and then connect that up to our app delegate in IB. Here's the revised <code>ContactStyleeViewController</code> interface file:</p>
<pre>#import &lt;UIKit/UIKit.h&gt;
@class ContactStyleeAppDelegate;

@interface ContactStyleeViewController : UIViewController
	&lt;UITableViewDataSource, UITableViewDelegate&gt; {

	NSArray *data;
	ContactStyleeAppDelegate *appDelegate;
}

@property (nonatomic, retain) NSArray *data;
@property (nonatomic, retain) IBOutlet ContactStyleeAppDelegate *appDelegate;

@end</pre>
<p>Note that we need to forward declare the <code>ContactStyleeAppDelegate</code> class rather than importing the header file in order to avoid a circular include. Once we've hooked up this outlet to the app delegate in IB, we're almost ready to go. We just need to tell the table view where to get the header view from.</p>
<p>To do this, we need to implement two new methods in <code>ContactStyleeViewController</code> that are optional methods on the <code>UITableViewDelegate</code> protocol, <code>tableView:viewForHeaderInSection</code> and <code>tableView:heightForHeaderInSection</code>. These are pretty simple methods now that we've hooked up the app controller outlet:</p>
<pre>- (UIView *)tableView:(UITableView *)tableView
	viewForHeaderInSection:(NSInteger)section {

	return [[appDelegate headerViewController] view];
}

- (CGFloat)tableView:(UITableView *)tableView
	heightForHeaderInSection:(NSInteger)section {

	return 85;
}</pre>
<p>At this point, I reckoned I was done, so I built and ran the app in the simulator. What I saw wasn't quite what I had expected:</p>
<p><img src="http://blog.jameshiggs.com/wp-content/uploads/2009/02/not-transparent1.png" alt="not_transparent.png" border="0" width="414" height="216" /></p>
<p>The header cell has an opaque white background, which is not what we wanted at all. We need to make a few simple adjustments in IB. Here's what the inspector looks like when the changes have been made (and you need to be careful that its the <em>view</em> that's selected in IB, not one of the controls):</p>
<p><img src="http://blog.jameshiggs.com/wp-content/uploads/2009/02/ib-settings.png" alt="ib_settings.png" border="0" width="301" height="404" /></p>
<p>You need to make sure that the "Opaque" checkbox is cleared, and that you set the background colour to have a 0% opacity. And that's it. Here's a screenshot:</p>
<p><img src="http://blog.jameshiggs.com/wp-content/uploads/2009/02/finished-app.png" alt="finished_app.png" border="0" width="413" height="243" /></p>
<p>And here's a video showing that it scrolls just like the built-in contacts app:</p>
<p><object width="193" height="371"><param name="movie" value="http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/jingswfplayer.swf"></param><param name="quality" value="high"></param><param name="bgcolor" value="#FFFFFF"></param><param name="flashVars" value="thumb=http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/FirstFrame.jpg&#038;width=386&#038;height=742&#038;content=http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/00000001.swf"></param><param name="allowFullScreen" value="true"></param><param name="scale" value="showall"></param><param name="allowScriptAccess" value="always"></param><param name="base" value="http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/"></param>  <embed src="http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="193" height="371" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/FirstFrame.jpg&#038;width=386&#038;height=742&#038;content=http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/00000001.swf" allowFullScreen="true" base="http://content.screencast.com/users/higgis/folders/Jing/media/2ac67cb6-830f-49d3-ab66-13d7a2770227/" scale="showall"></embed></object></p>
<p>It took me a while to figure out that this was the best way. Hopefully this post will help someone else to get there quicker. But, since I'm strictly an iPhone development beginner, I'd be really interested to hear from people if they think there's a better way to do it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jameshiggs.com/2009/03/01/transparent-table-header-uitableview/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

