<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-9017208940051771851</id><updated>2009-11-07T15:48:10.165-05:00</updated><title type="text">iPhone SDK Articles</title><subtitle type="html">iPhone SDK Tutorials, iPhone SDK Articles, XCode Tutorial, Interface Builder, Using Interface builder to create views.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.iphonesdkarticles.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default?start-index=26&amp;max-results=25" /><author><name>jai</name><uri>http://www.blogger.com/profile/09514342500729931901</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/iPhoneSDKArticles" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-3820065807619830703</id><published>2009-03-29T12:04:00.040-04:00</published><updated>2009-03-29T15:06:01.196-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">Drill down table view with a detail view</title><content type="html">&lt;span class="previewpost"&gt;Since I published my drill down table view tutorial, I got a lot of positive feedback but with one common request. How do I load a different detail view for an item or how do I load a UITabBarController in the detail view. In this tutorial I will show how to load a different detail view.&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html" uitableview="" indexed="" table="" view=""&gt;UITableView - Indexed table view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/03/uitableview-drill-down-table-view.html"&gt;UITableView - Drill down table view tutorial&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using a drill down table view we can display hierarchical data where the last view is responsible of displaying some detail information. This view in which the detail information is displayed can be the same for all the data in the table view (like my last &lt;a target="_blank" href="http://www.iphonesdkarticles.com/2009/03/uitableview-drill-down-table-view.html"&gt;tutorial&lt;/a&gt;) or it can be different based on the path that the user took. In this tutorial I will show you how to add a different detail view based on the path the user took to get to the last item. This tutorial is based on the UITableView - Drill down table view tutorial and borrows its source code.&lt;br /&gt;&lt;br /&gt;This is how one of the detail view looks like&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ixq8Dp4ESMo/Sc-qrEQzclI/AAAAAAAAAG4/EOqFoiQU9uA/s1600-h/detailview.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 166px; height: 320px;" src="http://1.bp.blogspot.com/_ixq8Dp4ESMo/Sc-qrEQzclI/AAAAAAAAAG4/EOqFoiQU9uA/s320/detailview.jpg" alt="" id="BLOGGER_PHOTO_ID_5318657341803164242" border="0" /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Loading a detail view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Let's take a step back and think about the browser and the HTML it renders. The browser doesn't know what it is going to display and it does not even know the style it should set for the HTML. All that information is present in the HTML and the browser simply renders everything on the screen.&lt;br /&gt;&lt;br /&gt;Does this mean that to display different data, I need different views even though the view looks the same? No, if the view looks the same you can reuse the same view again to display different data.&lt;br /&gt;&lt;br /&gt;Let us think about the navigation controller as the browser and the data in the plist file as the HTML. If we want to tell the browser to style certain elements of the page, we would put that information in the HTML. In a similar fashion, we can put the detail view information in the plist file which the navigation controller will display. You only need to set this information in the last node of the plist file. When it is time to display the detail view, the code can look at this field and show the right detail view to the user.&lt;br /&gt;&lt;br /&gt;Let us change the plist file from the last tutorial to include some information about the detail view.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Changing the plist file&lt;/span&gt;&lt;br /&gt;Here we will add a new item to the last child; the title that gets displayed before the detail view is shown. The item will have a title of "View", type will be number and the value will be 1, 2, or 3. Where 1 = display a UITabBarController in the detail view, 2 = display a detail view with an image in it, and 3 = display a simple detail view.&lt;br /&gt;&lt;br /&gt;Your plist file should look like this for the four items&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yk1r3OfI/AAAAAAAAAHA/i9XDQLAOjxE/s1600-h/ItemOne.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 78px;" src="http://4.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yk1r3OfI/AAAAAAAAAHA/i9XDQLAOjxE/s320/ItemOne.jpg" alt="" id="BLOGGER_PHOTO_ID_5318666030903933426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yoeUcSkI/AAAAAAAAAHI/kmV-2xqJcak/s1600-h/ItemTwo.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 113px;" src="http://3.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yoeUcSkI/AAAAAAAAAHI/kmV-2xqJcak/s320/ItemTwo.jpg" alt="" id="BLOGGER_PHOTO_ID_5318666093351160386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yrhk3GcI/AAAAAAAAAHQ/HROhEfxNfi0/s1600-h/ItemThree.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 148px;" src="http://3.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yrhk3GcI/AAAAAAAAAHQ/HROhEfxNfi0/s320/ItemThree.jpg" alt="" id="BLOGGER_PHOTO_ID_5318666145764940226" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yvL3FIGI/AAAAAAAAAHY/gsNZ9Qn5CWA/s1600-h/ItemFour.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 182px;" src="http://3.bp.blogspot.com/_ixq8Dp4ESMo/Sc-yvL3FIGI/AAAAAAAAAHY/gsNZ9Qn5CWA/s320/ItemFour.jpg" alt="" id="BLOGGER_PHOTO_ID_5318666208655253602" border="0" /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Recap&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We have added an extra item at the end of called "View" whose type is integer and value is either 1, 2, or 3. Where 1 = load a detail view UITabBarController, 2 = load a detail view with an image and 3 = load a simple detail view. Let's see how to add a detail view with a UITabBarController&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;Adding a UITabBarController to the detail view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Let's add a UITabBarController to the detail view. We will need an outlet of type UITabBarController, so lets create that in the header file of RootViewController. The code changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.h&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;NSArray *tableDataSource;&lt;br /&gt;NSString *CurrentTitle;&lt;br /&gt;NSInteger CurrentLevel;&lt;br /&gt;IBOutlet UITabBarController *tbController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSArray *tableDataSource;&lt;br /&gt;@property (nonatomic, retain) NSString *CurrentTitle;&lt;br /&gt;@property (nonatomic, readwrite) NSInteger CurrentLevel;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The dealloc method changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)dealloc {&lt;br /&gt;[tbController release];&lt;br /&gt;[CurrentTitle release];&lt;br /&gt;[tableDataSource release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Launch Interface Builder by double clicking "RootViewController.xib" file and drag and drop a UITabBarController in the nib file. Select File's Owner and select the outlet "tbController" and drag it over to the UITabBarController and release. Now we have connected the outlet tbController to the UITabBarController. Add two views in the UITabBarController and change the title of the UITabBarItems to say "View One" and "View Two". Also add a label to both the views which would say "View One" for the first and "View Two" for the second. This is all you have to do in the Interface Builder.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Display the detail view&lt;/span&gt;&lt;br /&gt;We now have to display the UITabBarController as a detail view when an item is selected in the UITableView. Before we do that let's stop for a while and see what we did. We added a UITabBarController in the same nib file as the RootViewController instead of creating a different nib file. When displaying a detail view, normally we would initialize the view controller and push it on top of the navigation controller. If we try to do the same here we would see the same table view again, which we do not want. The trick here is to switch the view of the RootViewController from the table view to the view of the tbController. Let's see how to do this; the code for tableView:didSelectRowAtIndexPath changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//Get the dictionary of the selected data source.&lt;br /&gt;NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Get the children of the present item.&lt;br /&gt;NSArray *Children = [dictionary objectForKey:@"Children"];&lt;br /&gt;&lt;br /&gt;if([Children count] == 0) {&lt;br /&gt; NSInteger ViewNumber = [[dictionary objectForKey:@"View"] integerValue];&lt;br /&gt; switch (ViewNumber) {&lt;br /&gt;  case 1: {&lt;br /&gt;   RootViewController *rvc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];&lt;br /&gt;   //Switch the view here&lt;br /&gt;   rvc.view = tbController.view;&lt;br /&gt;   [self.navigationController pushViewController:rvc animated:YES];&lt;br /&gt;   [rvc release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt;  case 2:&lt;br /&gt;   break;&lt;br /&gt;  case 3: {&lt;br /&gt;   DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;   [self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;   [dvController release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt;  default: {&lt;br /&gt;   DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;   [self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;   [dvController release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt; //Prepare to tableview.&lt;br /&gt; RootViewController *rvController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt; //Increment the Current View&lt;br /&gt; rvController.CurrentLevel += 1;&lt;br /&gt;&lt;br /&gt; //Set the title;&lt;br /&gt; rvController.CurrentTitle = [dictionary objectForKey:@"Title"];&lt;br /&gt;&lt;br /&gt; //Push the new table view on the stack&lt;br /&gt; [self.navigationController pushViewController:rvController animated:YES];&lt;br /&gt;&lt;br /&gt; rvController.tableDataSource = Children;&lt;br /&gt;&lt;br /&gt; [rvController release];&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;That is the complete code listing for tableView:didSelectRowAtIndexPath method but it does a lot of things and we only need to concentrate on some of the code, so teh condensed version is listed below&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m - tableView:didSelectRowAtIndexPath&lt;br /&gt;if([Children count] == 0) {&lt;br /&gt; NSInteger ViewNumber = [[dictionary objectForKey:@"View"] integerValue];&lt;br /&gt; switch (ViewNumber) {&lt;br /&gt;  case 1: {&lt;br /&gt;   RootViewController *rvc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];&lt;br /&gt;   //Switch the view here&lt;br /&gt;   rvc.view = tbController.view;&lt;br /&gt;   [self.navigationController pushViewController:rvc animated:YES];&lt;br /&gt;   [rvc release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt;  case 2:&lt;br /&gt;   break;&lt;br /&gt;  case 3: {&lt;br /&gt;   DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;   [self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;   [dvController release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt;  default: {&lt;br /&gt;   DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;   [self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;   [dvController release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The above code first checks if the present item has any children or not, if it doesn't then we look for the value of the item "View". If it is 1, we know that we have to display a detail view with a UITabBarController. As mentioned before we need to switch the view property of the controller to the view of the tab bar controller, which we do after initializing the controller. At last we ask the navigation controller to display our view which is connected to the controller.&lt;br /&gt;&lt;br /&gt;Test it out to see how it works.&lt;br /&gt;&lt;br /&gt;We also mentioned that if the "View" has a value of 3 then we would display the simple detail view. So drill down Item 3/4 and see the result. Don't do that with Item 2 yet because it will not work.&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Adding a detail view which will display an image.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Hopefully by now you have a clear idea of how to display different detail views when working with a drill down app.&lt;br /&gt;&lt;br /&gt;To display a view with an image create a new view and a new view controller and name the view "ImageView" and the view controller "ImageViewController". Open the ImageView in IB and set the class to be "ImageViewController" and connect the view outlet from the File's Owner to the view. Drag and drop a UIImageView from the library on the view. We will set the image of this UIImageView when the view loads and the name of the image will be passed from the root view controller. Since we need to display an image in the image view from Xcode we need an outlet of type UIImageView in the Interface Builder. The header file of "ImageViewController" changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//ImageViewController.m&lt;br /&gt;@interface ImageViewController : UIViewController {&lt;br /&gt;&lt;br /&gt;IBOutlet UIImageView *imgView;&lt;br /&gt;NSString *ImageName;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSString *ImageName;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We have also declared a property called "ImageName" which the root view controller will use to pass the name of the image to the image view controller and the image view controller will display the image in the image view.&lt;br /&gt;&lt;br /&gt;This is how the viewDidLoad method changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//ImageViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;NSString *Path = [[NSBundle mainBundle] bundlePath];&lt;br /&gt;NSString *ImagePath = [Path stringByAppendingPathComponent:ImageName];&lt;br /&gt;UIImage *tempImg = [[UIImage alloc] initWithContentsOfFile:ImagePath];&lt;br /&gt;[imgView setImage:tempImg];&lt;br /&gt;[tempImg release];&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The dealloc method looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//ImageViewController.m&lt;br /&gt;- (void)dealloc {&lt;br /&gt;[ImageName release];&lt;br /&gt;[imgView release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Displaying the detail view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Let's go back to the RootViewController.m file and import "ImageViewController.h" file at the top and it should look like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;#import "RootViewController.h"&lt;br /&gt;#import "DrillDownAppAppDelegate.h"&lt;br /&gt;#import "DetailViewController.h"&lt;br /&gt;#import "ImageViewController.h"&lt;br /&gt;&lt;br /&gt;@implementation RootViewController&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In tableView:didSelectRowAtIndexPath we will now display the image detail view when the "ViewNumber" is set to 2. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m - tableView:didSelectRowAtIndexPath method&lt;br /&gt;case 2: {&lt;br /&gt;   ImageViewController *ivc = [[ImageViewController alloc] initWithNibName:@"ImageView" bundle:[NSBundle mainBundle]];&lt;br /&gt;   ivc.ImageName = @"Image.jpg";&lt;br /&gt;   [self.navigationController pushViewController:ivc animated:YES];&lt;br /&gt;   [ivc release];&lt;br /&gt;   }&lt;br /&gt;   break;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the above code we initialize the "ImageViewController" and set the name of the image that it should display and ask the navigation controller to display it. Do not forget to place an image in the "Resources" folder.&lt;br /&gt;&lt;br /&gt;Build and Run to see how it works.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;I hope this helps you in some way on how to load a detail view with a UITabBarController. If you have any questions on loading a different detail view please take a look at this tutorial. Comments are most welcome and if you have any questions please send me an email at iphonearticles[@]gmail[dot]com.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/DrillDownAppDetailView.zip?attredirects=0"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html" uitableview="" indexed="" table="" view=""&gt;UITableView - Indexed table view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/03/uitableview-drill-down-table-view.html"&gt;UITableView - Drill down table view tutorial&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-3820065807619830703?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/EM_PYnogkp0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/3820065807619830703/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=3820065807619830703&amp;isPopup=true" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/3820065807619830703" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/3820065807619830703" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/EM_PYnogkp0/drill-down-table-view-with-detail-view.html" title="Drill down table view with a detail view" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_ixq8Dp4ESMo/Sc-qrEQzclI/AAAAAAAAAG4/EOqFoiQU9uA/s72-c/detailview.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/03/drill-down-table-view-with-detail-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-223464400925966628</id><published>2009-03-27T21:18:00.005-04:00</published><updated>2009-03-27T21:23:29.564-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><title type="text">SQLite and CoreData</title><content type="html">&lt;span class="previewpost"&gt;Yes, Apple has finally ported Core Data to the iPhone which means using SQLite in an application is not the best approach. Once the OS 3.0 is officially released, I will be posting more tutorials on using Core Data. Thank you for all your continued support.&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;Yes, Apple has finally ported Core Data to the iPhone which means using SQLite in an application is not the best approach. Once the OS 3.0 is officially released, I will be posting more tutorials on using Core Data. Thank you for all your continued support. continued support.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-223464400925966628?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/F2kQZCBfjp4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/223464400925966628/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=223464400925966628&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/223464400925966628" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/223464400925966628" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/F2kQZCBfjp4/sqlite-and-coredata.html" title="SQLite and CoreData" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/03/sqlite-and-coredata.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-4035581782973762136</id><published>2009-03-08T13:40:00.085-04:00</published><updated>2009-03-08T23:41:43.470-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Drill down table view tutorial</title><content type="html">&lt;span class="previewpost"&gt;Until now we saw how to create a simple table but there are times when we need to show another table view when a row is selected. This kind of a flow is called "drill down" and in this tutorial we learn how to create a drill down table view. Click on "Read more..." to learn more&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html" uitableview="" indexed="" table="" view=""&gt;UITableView - Indexed table view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Drill down table view tutorial&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using a drill down table view we can display some primary level of items, where a selected row will result in displaying a new table view with data related to the item selected. The process is repeated until an item has no sub level categories and it is then we display a detail view which is not a UITableView. This is the seventh tutorial in the UITableView series and does NOT inherit its source code from the previous tutorial.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating the project&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new project in XCode by selecting "Navigation-Based Application", I have named my project "DrillDownApp" which is used in this tutorial.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Using nothing but a single UITableView&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Instead of creating 3 different UITableView's to display three different levels, we will use the same table view and the same table view controller. This philosophy is borrowed from web programming, where we only have one page to display a list of products.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Designing the flow&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Before we start writing any code, let's decide the flow of the application with some specifics. Below is a table of how the data movies when we select an item.&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="90%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-weight: bold;"&gt;First Level&lt;/td&gt;&lt;td style="font-weight: bold;"&gt;Second Level&lt;/td&gt;&lt;td style="font-weight: bold;"&gt;Third Level&lt;/td&gt;&lt;td style="font-weight: bold;"&gt;Fourth Level&lt;/td&gt;&lt;td style="font-weight: bold;"&gt;Fifth Level&lt;/td&gt;&lt;td style="font-weight: bold;"&gt;Sixth Level&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Item 1&lt;/td&gt;&lt;td&gt;Screen A&lt;/td&gt;&lt;td&gt;Detail View&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Item 2&lt;/td&gt;&lt;td&gt;Screen B&lt;/td&gt;&lt;td&gt;Screen C&lt;/td&gt;&lt;td&gt;Detail View&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Item 3&lt;/td&gt;&lt;td&gt;Screen D&lt;/td&gt;&lt;td&gt;Screen E&lt;/td&gt;&lt;td&gt;Screen F&lt;/td&gt;&lt;td&gt;Detail View&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Item 4&lt;/td&gt;&lt;td&gt;Screen G&lt;/td&gt;&lt;td&gt;Screen H&lt;/td&gt;&lt;td&gt;Screen I&lt;/td&gt;&lt;td&gt;Screen J&lt;/td&gt;&lt;td&gt;Detail View&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;When the application is launched we will see the following items;  "Item 1", "Item 2", "Item 3", and "Item 4". If "Item 1" is selected then we see the table view display "Screen A" and upon selecting "Screen A" we will see the detail view load. The same goes for "Item 2", which will load a table view with one value called "Screen B" -&gt; "Screen C" -&gt; Detail view and so on so forth for the remaining values in the first table view.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating the data source&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The data source for this tutorial will come from an XML file or a plist file. Create a new file under the "Resource" folder by clicking on File -&gt; New File -&gt; (Under MAC OS X) select Other -&gt; Property List and save this new file by giving it a name of "Data.plist". Let's start by adding values to this property list file.&lt;br /&gt;&lt;br /&gt;Select the "Root" element and create a new item by clicking on the arrows at the right.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ixq8Dp4ESMo/SbSMfAdQw6I/AAAAAAAAAGw/1OE5Ie9u27M/s1600-h/Image1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 23px;" src="http://3.bp.blogspot.com/_ixq8Dp4ESMo/SbSMfAdQw6I/AAAAAAAAAGw/1OE5Ie9u27M/s320/Image1.jpg" alt="" id="BLOGGER_PHOTO_ID_5311024324903224226" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Name the item "Rows" and change its type to "Array". This is the array which will contain all the primary level items with its children. The user should be able to select an item in a table view and load another table view with all items under the selected item in the first table view. For us to achieve this, our array should contain a dictionary with at least two types of fields; string and a array. The string type will hold the value of the cell and the array will hold the children rows, which again will contain a n number of dictionaries where n is the number of children rows an item will have.&lt;br /&gt;&lt;br /&gt;Create a new item "Rows" and set its type to "Dictionary", you do not have to change the key of the dictionary. Select the dictionary item and create a new item and set its data type to string and name the key to "Title". The name of the key which should not be changed throughout the property list file, since this is the key which will contain the value of the cell which shows up in the UITableViewCell. Set its value to "Item 1" since this is the first item that shows up in the table view. From the above table we know that selecting "Item 1" should reload the table view to display "Screen A". Create another field under "Item 1" and change its type to an Array and set its key to "Children". Under the "Children" item create another item of type "Dictionary" which will only contain a string value called "Screen A" with its key set to "Title". If "Screen A" is selected we load the detail view; so we do not have to add any children at this level. Add the remaining items from the table in the property list and when you are done the property list should look like &lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/Home/uitableviewdilldown/Data.plist?attredirects=0"&gt;this&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Populating the data source&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Now that we have created the data source, the next step is to populate it which will be done in the application delegate. Since the root element of data.plist is of type "Dictionary", we will create a variable of type NSDictionary to hold all the data from the property list file. The header file of the application delegate changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DrillDownAppDelegate.h&lt;br /&gt;@interface DrillDownAppAppDelegate : NSObject &amp;lt;UIApplicationDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt;UIWindow *window;&lt;br /&gt;UINavigationController *navigationController;&lt;br /&gt;&lt;br /&gt;NSDictionary *data;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UIWindow *window;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSDictionary *data;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The variable "data" will hold our data source which is also synthesized in the implementation file and released in the dealloc method (code not shown here).&lt;br /&gt;&lt;br /&gt;This is how the data is populated in applicationDidFinishLaunching method&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DrillDownAppDelegate.m&lt;br /&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;NSString *Path = [[NSBundle mainBundle] bundlePath];&lt;br /&gt;NSString *DataPath = [Path stringByAppendingPathComponent:@"data.plist"];&lt;br /&gt;&lt;br /&gt;NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];&lt;br /&gt;self.data = tempDict;&lt;br /&gt;[tempDict release];&lt;br /&gt;&lt;br /&gt;// Configure and show the window&lt;br /&gt;[window addSubview:[navigationController view]];&lt;br /&gt;[window makeKeyAndVisible];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We read the "data.plist" file and read all of its data in a dictionary object using initWithContentsOfFile message which is present in the NSDictionary class.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Display the data in the table view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Since we will be using the same table view to display data at level, we need; an array to hold the data for the current level, a string to hold the item selected in the parent level and an integer value to tell us if this is the first level or not. This is how the header file for RootViewController changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.h&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;NSArray *tableDataSource;&lt;br /&gt;NSString *CurrentTitle;&lt;br /&gt;NSInteger CurrentLevel;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSArray *tableDataSource;&lt;br /&gt;@property (nonatomic, retain) NSString *CurrentTitle;&lt;br /&gt;@property (nonatomic, readwrite) NSInteger CurrentLevel;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The property "tableDataSource" contains the present level data source and mimicks the property list file. The array will contain n number of dictionary objects, where n is the number of rows at any given level. A dictionary will contain a title and an array containing the children of the present item. All the properties have been synthesized and the "tableDataSource" and "CurrentTitle" have been released in the dealloc method.&lt;br /&gt;&lt;br /&gt;The method viewDidLoad changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;if(CurrentLevel == 0) {&lt;br /&gt;&lt;br /&gt;//Initialize our table data source&lt;br /&gt;NSArray *tempArray = [[NSArray alloc] init];&lt;br /&gt;self.tableDataSource = tempArray;&lt;br /&gt;[tempArray release];&lt;br /&gt;&lt;br /&gt;DrillDownAppAppDelegate *AppDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;self.tableDataSource = [AppDelegate.data objectForKey:@"Rows"];&lt;br /&gt;&lt;br /&gt;self.navigationItem.title = @"Root";&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;self.navigationItem.title = CurrentTitle;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;If the value of the "CurrentLevel" is zero (which it will be when the application is launched) then the array is initialized and populated from the application delegate.  Here we get the array whose key is set to "Rows" which will contain the primary level data and the children of every item. The title of the navigation item is set to "Root" in this case, if not the title is set to the "CurrentTitle" variable and the "tableDataSource" is left untouched. These two properties are set in tableView:didSelectRowAtIndexPath method which will look at it later.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Displaying data&lt;/span&gt;&lt;br /&gt;In tableView:numberOfRowsInSection return the count of the array like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {&lt;br /&gt;return [self.tableDataSource count];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method tableView:cellForRowAtIndexPath changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Set up the cell...&lt;br /&gt;NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];&lt;br /&gt;cell.text = [dictionary objectForKey:@"Title"];&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;From the data source that we created, we know that every array has at least one element of type "Dictionary" and that has at least one element with the key "Title" which is the string that gets displayed in the table view cell. After the UITableView cell is created, we get the dictionary object from the array and the value for the key "Title", which is set to the text property of the cell.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Select a row&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When a row is selected tableView:didSelectRowAtIndexPath method is called and this is how it looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//Get the dictionary of the selected data source.&lt;br /&gt;NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Get the children of the present item.&lt;br /&gt;NSArray *Children = [dictionary objectForKey:@"Children"];&lt;br /&gt;&lt;br /&gt;if([Children count] == 0) {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;//Prepare to tableview.&lt;br /&gt;RootViewController *rvController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt;//Increment the Current View&lt;br /&gt;rvController.CurrentLevel += 1;&lt;br /&gt;&lt;br /&gt;//Set the title;&lt;br /&gt;rvController.CurrentTitle = [dictionary objectForKey:@"Title"];&lt;br /&gt;&lt;br /&gt;//Push the new table view on the stack&lt;br /&gt;[self.navigationController pushViewController:rvController animated:YES];&lt;br /&gt;&lt;br /&gt;rvController.tableDataSource = Children;&lt;br /&gt;&lt;br /&gt;[rvController release];&lt;br /&gt;}&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We first get dictionary object of the selected row and then get its children into an array. If the present level does not have any children we do not do anything for now, but if it does; we load the same table view with different set of data. We initialized the same "RootViewcontroller", increment the "CurrentLevel" value so it is not zero, set the selected cell's text as the "CurrentTitle", push the view controller on the top of the stack and set the new data source to the "tableDataSource" property.&lt;br /&gt;&lt;br /&gt;Try it out and you will be able to drill down by selecting a row.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Loading the detail view&lt;/span&gt;&lt;br /&gt;Create a new view (using IB) and name it "DetailView", remember the views get stored under the "Resources" folder. Create a new UIViewController in Xcode under the "Classes" folder and name it DetailViewController. Set the class of File's owner of the "DetailView" to "DetailViewController" and connect the view outlet to the object in the view in the nib file. Please refer to this tutorial on how to load a detail view.&lt;br /&gt;&lt;br /&gt;In viewDidLoad method of the "DetailViewController" set the title of the view to "Detail View". This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;self.navigationItem.title = @"Detail View";&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We will load the detail view when an item does not have any children. The tableView:didSelectRowAtIndexPath method changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//Get the dictionary of the selected data source.&lt;br /&gt;NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Get the children of the present item.&lt;br /&gt;NSArray *Children = [dictionary objectForKey:@"Children"];&lt;br /&gt;&lt;br /&gt;if([Children count] == 0) {&lt;br /&gt;&lt;br /&gt;DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;[self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;[dvController release];&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;//Prepare to tableview.&lt;br /&gt;RootViewController *rvController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt;//Increment the Current View&lt;br /&gt;rvController.CurrentLevel += 1;&lt;br /&gt;&lt;br /&gt;//Set the title;&lt;br /&gt;rvController.CurrentTitle = [dictionary objectForKey:@"Title"];&lt;br /&gt;&lt;br /&gt;//Push the new table view on the stack&lt;br /&gt;[self.navigationController pushViewController:rvController animated:YES];&lt;br /&gt;&lt;br /&gt;rvController.tableDataSource = Children;&lt;br /&gt;&lt;br /&gt;[rvController release];&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using this design we can add any number of children to an item without changing the code. If we have to add data to the sixth level we need not create another table view, all we have to do is add another item in our data source and the code will handle the change. This design does use n number of table view objects like the example provided by Apple.&lt;br /&gt;&lt;br /&gt;I hope you had fun reading this article as much as I had writing it. Please let me know what you think.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/DrillDownApp.zip?attredirects=0"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading data in a detail view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching the UITableView&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html" uitableview="" indexed="" table="" view=""&gt;UITableView - Indexed table view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Drill down table view tutorial&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-4035581782973762136?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/CzFuUrzrinI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/4035581782973762136/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=4035581782973762136&amp;isPopup=true" title="31 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/4035581782973762136" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/4035581782973762136" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/CzFuUrzrinI/uitableview-drill-down-table-view.html" title="UITableView - Drill down table view tutorial" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_ixq8Dp4ESMo/SbSMfAdQw6I/AAAAAAAAAGw/1OE5Ie9u27M/s72-c/Image1.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">31</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/03/uitableview-drill-down-table-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-7173910114708786641</id><published>2009-02-11T22:10:00.045-05:00</published><updated>2009-02-12T00:37:21.552-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">SQLite Tutorial - Saving images in the database</title><content type="html">&lt;span class="previewpost"&gt;There maybe times when you need to save more than just text in the database, like a file or an image. SQLite versions 3.0 and later allows you to store BLOB data in a column. Using the data type BLOB we can store large objects like an image or a file. Read on to learn more.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Saving images in the database&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using &lt;a target="_blank" href="http://www.sqlite.org/faq.html#q10"&gt;BLOB&lt;/a&gt; data type we can store an image in the &lt;a href="http://www.sqlite.org/index.html" target="_blank"&gt;SQLite&lt;/a&gt; database. The data that actually gets stored in the database is the bytes that make up an image or a file. The is the sixth tutorial in SQLite tutorial series and borrows its source code from the previous one. We will change the "DetailView" by adding a new section which will be used to display or change the image. The image can only be changed when the view is in the edit mode. We will use a &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html" target="_blank"&gt;UIImagePickerController&lt;/a&gt; to display the photo album and to select an image.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Changing the database&lt;/span&gt;&lt;br /&gt;Let's start by adding a new column to our "Coffee" database. Name the column "CoffeeImage" and set its data type to BLOB. This is how the database schema looks like in &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5817" target="_blank"&gt;SQLite manager&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ixq8Dp4ESMo/SZOr5Tv4eHI/AAAAAAAAAFw/LMLuKQB6bdA/s1600-h/Schema.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 199px;" src="http://3.bp.blogspot.com/_ixq8Dp4ESMo/SZOr5Tv4eHI/AAAAAAAAAFw/LMLuKQB6bdA/s320/Schema.jpg" alt="" id="BLOGGER_PHOTO_ID_5301770187387205746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Changing the Coffee Class&lt;/span&gt;&lt;br /&gt;Add a new property to the "Coffee" class which will hold the image from the database. This is how the header and the implementation files look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Coffee.h&lt;br /&gt;//Complete code listing not shown&lt;br /&gt;@interface Coffee : NSObject {&lt;br /&gt;&lt;br /&gt; NSInteger coffeeID;&lt;br /&gt; NSString *coffeeName;&lt;br /&gt; NSDecimalNumber *price;&lt;br /&gt; UIImage *coffeeImage;&lt;br /&gt;//Complete Code listing not shown ...&lt;br /&gt;}&lt;br /&gt;@property (nonatomic, readonly) NSInteger coffeeID;&lt;br /&gt;@property (nonatomic, copy) NSString *coffeeName;&lt;br /&gt;@property (nonatomic, copy) NSDecimalNumber *price;&lt;br /&gt;@property (nonatomic, retain) UIImage *coffeeImage;&lt;br /&gt;//Complete Code listing not shown ...&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The new property is synthesized and released in the dealloc method&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Coffee.m&lt;br /&gt;//Complete code listing now shown&lt;br /&gt;@synthesize coffeeID, coffeeName, price, isDirty, isDetailViewHydrated, coffeeImage;&lt;br /&gt;&lt;br /&gt;- (void)setCoffeeImage:(UIImage *)theCoffeeImage {&lt;br /&gt; &lt;br /&gt; self.isDirty = YES;&lt;br /&gt; [coffeeImage release];&lt;br /&gt; coffeeImage = [theCoffeeImage retain];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) dealloc {&lt;br /&gt; &lt;br /&gt; [coffeeImage release];&lt;br /&gt; [price release];&lt;br /&gt; [coffeeName release];&lt;br /&gt; [super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Changing the Detail View&lt;/span&gt;&lt;br /&gt;Let's add a new row to the detail view, which will be used to display the image or to change the image in edit mode. Since the style of the table view placed on the detail view is set to "Grouped", we will return three sections in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/numberOfSectionsInTableView:" target="_blank"&gt;numberOfSectionsInTableView&lt;/a&gt; and this is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.h&lt;br /&gt;- (NSInteger)numberOfSectionsInTableView:(UITableView *)tblView {&lt;br /&gt;return 3;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's also display a title for the new section in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:titleForHeaderInSection:" target="_blank"&gt;tableView:titleForHeaderInSection&lt;/a&gt;. The code changes like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (NSString *)tableView:(UITableView *)tblView titleForHeaderInSection:(NSInteger)section {&lt;br /&gt; &lt;br /&gt; NSString *sectionName = nil;&lt;br /&gt; &lt;br /&gt; switch (section) {&lt;br /&gt;  case 0:&lt;br /&gt;   sectionName = [NSString stringWithFormat:@"Coffee Name"];&lt;br /&gt;   break;&lt;br /&gt;  case 1:&lt;br /&gt;   sectionName = [NSString stringWithFormat:@"Price"];&lt;br /&gt;   break;&lt;br /&gt;  case 2:&lt;br /&gt;   sectionName = [NSString stringWithFormat:@"Coffee Image"];&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return sectionName;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Displaying the photo album&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Now we need to display a photo album when the section is selected in edit mode. From this album we can select a image to be saved in the database. Using a &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html" target="_blank"&gt;UIImagePickerController&lt;/a&gt; we can capture an image from the camera or the photo library on the device. UIImagePickerController class manages all the user interactions and all we have to do is display and dismiss it. Before we can display the view, we need to check if the interface is supported by calling &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/occ/clm/UIImagePickerController/isSourceTypeAvailable:" target="_blank"&gt;isSourceTypeAvailable&lt;/a&gt; class method. The delegate of the UIImagePickerController should also confirm to &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationControllerDelegate_Protocol/Reference/Reference.html" target="_blank"&gt;UINavigationControllerDelegate&lt;/a&gt; and &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIImagePickerControllerDelegate_Protocol/UIImagePickerControllerDelegate/UIImagePickerControllerDelegate.html#//apple_ref/occ/intf/UIImagePickerControllerDelegate" target="_blank"&gt;UIImagePickerControllerDelegate&lt;/a&gt;. In this case we will set the delegate of UIImagePickerController to "DetailViewController" and this is how the header and implementation file changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.h&lt;br /&gt;@class Coffee, EditViewController;&lt;br /&gt;&lt;br /&gt;@interface DetailViewController : UIViewController &amp;lt;UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITableViewDataSource, UITableViewDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt; IBOutlet UITableView *tableView;&lt;br /&gt; Coffee *coffeeObj;&lt;br /&gt; NSIndexPath *selectedIndexPath;&lt;br /&gt; EditViewController *evController;&lt;br /&gt; &lt;br /&gt; UIImagePickerController *imagePickerView;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) Coffee *coffeeObj;&lt;br /&gt;&lt;br /&gt;@end&lt;/uinavigationcontrollerdelegate,&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The variable "imagePickerView" is released in the dealloc method and the code listing is now shown here. We will initialize "imagePickerView" in viewDidLoad method and this is how the code changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt; &lt;br /&gt; self.navigationItem.rightBarButtonItem = self.editButtonItem;&lt;br /&gt; &lt;br /&gt; //Configure the UIImagePickerController&lt;br /&gt; imagePickerView = [[UIImagePickerController alloc] init];&lt;br /&gt; imagePickerView.delegate = self;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;From the above code, "imagePickerView" is initialized and its delegate is set to self. This way "DetailViewController" will be notified of all the user actions on the picker controller. First, we need to display the view and it is done in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:" target="_blank"&gt;tableView:didSelectRowAtIndexPath&lt;/a&gt; and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (void)tableView:(UITableView *)tblView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt; &lt;br /&gt; //Keep track of the row selected.&lt;br /&gt; selectedIndexPath = indexPath;&lt;br /&gt; &lt;br /&gt; if(evController == nil)&lt;br /&gt;  evController = [[EditViewController alloc] initWithNibName:@"EditView" bundle:nil];&lt;br /&gt; &lt;br /&gt; //Find out which field is being edited.&lt;br /&gt; switch(indexPath.section)&lt;br /&gt; {&lt;br /&gt;  case 0:&lt;br /&gt;   evController.keyOfTheFieldToEdit = @"coffeeName";&lt;br /&gt;   evController.editValue = coffeeObj.coffeeName;&lt;br /&gt;   &lt;br /&gt;   //Object being edited.&lt;br /&gt;   evController.objectToEdit = coffeeObj;&lt;br /&gt;   &lt;br /&gt;   //Push the edit view controller on top of the stack.&lt;br /&gt;   [self.navigationController pushViewController:evController animated:YES];&lt;br /&gt;   break;&lt;br /&gt;  case 1:&lt;br /&gt;   evController.keyOfTheFieldToEdit = @"price";&lt;br /&gt;   evController.editValue = [coffeeObj.price stringValue];&lt;br /&gt;   &lt;br /&gt;   //Object being edited.&lt;br /&gt;   evController.objectToEdit = coffeeObj;&lt;br /&gt;   &lt;br /&gt;   //Push the edit view controller on top of the stack.&lt;br /&gt;   [self.navigationController pushViewController:evController animated:YES];&lt;br /&gt;   break;&lt;br /&gt;  case 2:&lt;br /&gt;   if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])&lt;br /&gt;    [self presentModalViewController:imagePickerView animated:YES];&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;First confirm if the photo library is available on the device or not, if it is then present the view to the user. The method &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIImagePickerControllerDelegate_Protocol/UIImagePickerControllerDelegate/UIImagePickerControllerDelegate.html#//apple_ref/occ/intfm/UIImagePickerControllerDelegate/imagePickerController:didFinishPickingImage:editingInfo:" target="_blank"&gt;imagePickerController:didFinishPickingImage:editingInfo&lt;/a&gt; is called when an image is selected. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)dictionary {&lt;br /&gt;&lt;br /&gt; coffeeObj.coffeeImage = image;&lt;br /&gt; [tableView reloadData];&lt;br /&gt; [picker dismissModalViewControllerAnimated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We get the selected image and set the "coffeeImage" property of the selected coffee. The table view is then reloaded and the picker view is dismissed.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Display the coffee image&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We will display the coffee image in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/cellForRowAtIndexPath:" target="_blank"&gt;tableView:cellForRowAtIndexPath&lt;/a&gt; and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt; static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;   cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt; switch(indexPath.section) {&lt;br /&gt;  case 0:&lt;br /&gt;   cell.text = coffeeObj.coffeeName;&lt;br /&gt;   break;&lt;br /&gt;  case 1:&lt;br /&gt;   cell.text = [NSString stringWithFormat:@"%@", coffeeObj.price];&lt;br /&gt;   break;&lt;br /&gt;  case 2:&lt;br /&gt;   cell.text = @"Change Image";&lt;br /&gt;   if(coffeeObj.coffeeImage != nil)&lt;br /&gt;    cell.image = coffeeObj.coffeeImage;&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;If the index of the section is 2 then we set the title of the cell to "Change Image" and the image to the coffee image.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;Saving image in the SQLite database&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Until now we haven't saved the image in the database because we only save data when the application is being terminated or if a memory warning is received. The data is saved in "saveAllData" method as seen in the previous tutorial. Let's change this method to save the image in the database which now has a new column called "CoffeeImage" to hold the image as bytes. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Coffee.m&lt;br /&gt;- (void) saveAllData {&lt;br /&gt; &lt;br /&gt; if(isDirty) {&lt;br /&gt;  &lt;br /&gt;  if(updateStmt == nil) {&lt;br /&gt;   const char *sql = "update Coffee Set CoffeeName = ?, Price = ?, CoffeeImage = ? Where CoffeeID = ?";&lt;br /&gt;   if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;updateStmt, NULL) != SQLITE_OK)&lt;br /&gt;    NSAssert1(0, @"Error while creating update statement. '%s'", sqlite3_errmsg(database));&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  sqlite3_bind_text(updateStmt, 1, [coffeeName UTF8String], -1, SQLITE_TRANSIENT);&lt;br /&gt;  sqlite3_bind_double(updateStmt, 2, [price doubleValue]);&lt;br /&gt;  &lt;br /&gt;  NSData *imgData = UIImagePNGRepresentation(self.coffeeImage);&lt;br /&gt;  &lt;br /&gt;  int returnValue = -1;&lt;br /&gt;  if(self.coffeeImage != nil)&lt;br /&gt;   returnValue = sqlite3_bind_blob(updateStmt, 3, [imgData bytes], [imgData length], NULL);&lt;br /&gt;  else&lt;br /&gt;   returnValue = sqlite3_bind_blob(updateStmt, 3, nil, -1, NULL);&lt;br /&gt;  &lt;br /&gt;  sqlite3_bind_int(updateStmt, 4, coffeeID);&lt;br /&gt;  &lt;br /&gt;  if(returnValue != SQLITE_OK)&lt;br /&gt;   NSLog(@"Not OK!!!");&lt;br /&gt;  &lt;br /&gt;  if(SQLITE_DONE != sqlite3_step(updateStmt))&lt;br /&gt;   NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(database));&lt;br /&gt;  &lt;br /&gt;  sqlite3_reset(updateStmt);&lt;br /&gt;  &lt;br /&gt;  isDirty = NO;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //Reclaim all memory here.&lt;br /&gt; [coffeeName release];&lt;br /&gt; coffeeName = nil;&lt;br /&gt; [price release];&lt;br /&gt; price = nil;&lt;br /&gt; &lt;br /&gt; isDetailViewHydrated = NO;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We first rewrite the update query to include the CoffeeImage column. We also need a way to get the image data as bytes and this is where &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIKitFunctionReference/Reference/reference.html#//apple_ref/c/func/UIImagePNGRepresentation" target="_blank"&gt;UIImagePNGRepresentation&lt;/a&gt; method helps us. We then bind the BLOB parameter using &lt;a href="http://www.sqlite.org/c3ref/bind_blob.html" target="_blank"&gt;sqlite3_bind_blob&lt;/a&gt; method. The first parameter takes the update statement, the second parameter takes the index of the parameter value, the third one is the actual data itself, the fourth one is the length of the data which is being saved, and a pointer to a method which is responsible to clean up the data. If sqlite3_bind_blob method does not return &lt;a href="http://www.sqlite.org/c3ref/c_abort.html" target="_blank"&gt;SQLITE_OK&lt;/a&gt; then we display an error in NSLog. If there is no error while saving the data then we have successfully saved the image in the SQLite database on the iPhone/iPod.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Getting an image from the SQLite database&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We now have to get the data from the database when the detail view is loaded. This is done in "hydrateDetailViewData" method and this is how the code changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.m&lt;br /&gt;- (void) hydrateDetailViewData {&lt;br /&gt; &lt;br /&gt; //If the detail view is hydrated then do not get it from the database.&lt;br /&gt; if(isDetailViewHydrated) return;&lt;br /&gt; &lt;br /&gt; if(detailStmt == nil) {&lt;br /&gt;  const char *sql = "Select price, CoffeeImage from Coffee Where CoffeeID = ?";&lt;br /&gt;  if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;detailStmt, NULL) != SQLITE_OK)&lt;br /&gt;   NSAssert1(0, @"Error while creating detail view statement. '%s'", sqlite3_errmsg(database));&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; sqlite3_bind_int(detailStmt, 1, coffeeID);&lt;br /&gt; &lt;br /&gt; if(SQLITE_DONE != sqlite3_step(detailStmt)) {&lt;br /&gt;  &lt;br /&gt;  //Get the price in a temporary variable.&lt;br /&gt;  NSDecimalNumber *priceDN = [[NSDecimalNumber alloc] initWithDouble:sqlite3_column_double(detailStmt, 0)];&lt;br /&gt;  &lt;br /&gt;  //Assign the price. The price value will be copied, since the property is declared with "copy" attribute.&lt;br /&gt;  self.price = priceDN;&lt;br /&gt;  &lt;br /&gt;  NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(detailStmt, 1) length:sqlite3_column_bytes(detailStmt, 1)];&lt;br /&gt;  &lt;br /&gt;  if(data == nil)&lt;br /&gt;   NSLog(@"No image found.");&lt;br /&gt;  else&lt;br /&gt;   self.coffeeImage = [UIImage imageWithData:data];&lt;br /&gt;  &lt;br /&gt;  //Release the temporary variable. Since we created it using alloc, we have own it.&lt;br /&gt;  [priceDN release];&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt;  NSAssert1(0, @"Error while getting the price of coffee. '%s'", sqlite3_errmsg(database));&lt;br /&gt; &lt;br /&gt; //Reset the detail statement.&lt;br /&gt; sqlite3_reset(detailStmt);&lt;br /&gt; &lt;br /&gt; //Set isDetailViewHydrated as YES, so we do not get it again from the database.&lt;br /&gt; isDetailViewHydrated = YES;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The select query is changed to include CoffeeImage column and we use &lt;a href="http://www.sqlite.org/c3ref/column_blob.html" target="_blank"&gt;sqlite3_column_blob&lt;/a&gt; method to load the BLOB data into variable of type NSData. WE create an image of type &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html" target="_blank"&gt;NSData&lt;/a&gt; from &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIImage_Class/Reference/Reference.html#//apple_ref/occ/clm/UIImage/imageWithData:" target="_blank"&gt;imageWithData&lt;/a&gt; class method. The rest of the code works as described above.&lt;br /&gt;&lt;br /&gt;This tutorial wasn't designed to display imags anywhere and is a direct result of all the emails I got asking, how to save images in the SQLite database. So if you choose an image which does not fit in the section, it will take up all the space on the view.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;This tutorial explains how to save and read images from a SQLite database. We can use the same functionality to save files in the database. I hope you had fun and learnt something new with this tutorial.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/SQL6.zip?attredirects=0"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Selecting Data&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Saving images in the database&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-7173910114708786641?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/ymjMWZjdHIE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/7173910114708786641/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=7173910114708786641&amp;isPopup=true" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7173910114708786641" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7173910114708786641" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/ymjMWZjdHIE/sqlite-tutorial-saving-images-in.html" title="SQLite Tutorial - Saving images in the database" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_ixq8Dp4ESMo/SZOr5Tv4eHI/AAAAAAAAAFw/LMLuKQB6bdA/s72-c/Schema.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">14</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-5562533964127095331</id><published>2009-02-01T14:16:00.039-05:00</published><updated>2009-02-13T00:17:52.764-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Adding subviews to a cell's content view</title><content type="html">&lt;span class="previewpost"&gt;Using the default UITableViewCell we can display a text or an image but sometimes it is not good enough. In this tutorial you will learn how to customize the UITableViewCell. &lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html" uitableview="" indexed="" table="" view=""&gt;UITableView - Indexed table view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;UITableView - Adding subviews to a cell's content view&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using the default &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/cl/UITableViewCell"&gt;UITableViewCell&lt;/a&gt;, we can display a text (using the text property) or an image (using the image property). However, we cannot display data in multiple columns or rows. This is the sixth tutorial in the UITableView tutorial series and borrows its source code from the previous one. This is how the final app will look like&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh3.ggpht.com/_ixq8Dp4ESMo/SYuf0abKXEI/AAAAAAAAAEg/gPRseXSx8OA/s576/FinalApp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://lh3.ggpht.com/_ixq8Dp4ESMo/SYuf0abKXEI/AAAAAAAAAEg/gPRseXSx8OA/s576/FinalApp.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span class="fullpost"&gt;We cannot achieve the display we want by setting the text property of the UITableViewCell. To solve this problem, we are going to add two labels to the &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/contentView" target="_blank"&gt;content view&lt;/a&gt; of the cell. The labels are added in such a way that they show up one above the other by using coordinates. Apple documentation says we should add subviews to the cell's content view, if you do not want to change the default behavior of the cell. This is the reason why we are not going to inherit from UITableViewCell.&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Adding Sub Views&lt;/span&gt;&lt;br /&gt;Instead of creating a cell by using &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableViewCell/initWithFrame:reuseIdentifier:"&gt;initWithFrame:reuseIdentifier&lt;/a&gt;, we will create it from our own custom method. This method will be responsible for not only creating the cell but also the labels. The labels are created with specific locations in the cell using x and y coordinates. They are added to the content view of the cell as seen below&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class OverlayViewController;&lt;br /&gt;&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;NSMutableArray *listOfItems;&lt;br /&gt;NSMutableArray *copyListOfItems;&lt;br /&gt;IBOutlet UISearchBar *searchBar;&lt;br /&gt;BOOL searching;&lt;br /&gt;BOOL letUserSelectRow;&lt;br /&gt;&lt;br /&gt;OverlayViewController *ovController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier;&lt;br /&gt;- (void) searchTableView;&lt;br /&gt;- (void) doneSearching_Clicked:(id)sender;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;//RootViewController.m&lt;br /&gt;- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {&lt;br /&gt;&lt;br /&gt;CGRect CellFrame = CGRectMake(0, 0, 300, 60);&lt;br /&gt;CGRect Label1Frame = CGRectMake(10, 10, 290, 25);&lt;br /&gt;CGRect Label2Frame = CGRectMake(10, 33, 290, 25);&lt;br /&gt;UILabel *lblTemp;&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];&lt;br /&gt;&lt;br /&gt;//Initialize Label with tag 1.&lt;br /&gt;lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];&lt;br /&gt;lblTemp.tag = 1;&lt;br /&gt;[cell.contentView addSubview:lblTemp];&lt;br /&gt;[lblTemp release];&lt;br /&gt;&lt;br /&gt;//Initialize Label with tag 2.&lt;br /&gt;lblTemp = [[UILabel alloc] initWithFrame:Label2Frame];&lt;br /&gt;lblTemp.tag = 2;&lt;br /&gt;lblTemp.font = [UIFont boldSystemFontOfSize:12];&lt;br /&gt;lblTemp.textColor = [UIColor lightGrayColor];&lt;br /&gt;[cell.contentView addSubview:lblTemp];&lt;br /&gt;[lblTemp release];&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The above method creates three rectangles: one for the cell and for the two labels in the cell. We create the cell using initWithFrame:reuseIdentifier, but this time we add two labels to the content view property. Initialize the first label with "Label1Frame" coordinates, which will make this label show up at the top of the cell. Set the tag of this label to 1, so we can find it in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/cellForRowAtIndexPath:"&gt;tableView:cellForRowAtIndexPath&lt;/a&gt; method. Initialize the second label using "Label2"Frame" coordinates, which will make this label to show up at the bottom. The tag of this label is set to 2. The labels are added to the content view using &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/addSubview:"&gt;addSubView&lt;/a&gt; method. Finally the cell is returned to be reused.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Displaying data&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;&lt;span class="fullpost"&gt;&lt;span style=""&gt;Once we have the table view cell, we can get the underlying label by passing &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/viewWithTag:"&gt;viewWithTag&lt;/a&gt; message to the cell. Here the data is set to the text property of the label and not the cell. This is how the code for &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:cellForRowAtIndexPath:"&gt;tableView:cellForRowAtIndexPath&lt;/a&gt; changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;&lt;br /&gt;if(cell == nil)&lt;br /&gt; cell = [self getCellContentView:CellIdentifier];&lt;br /&gt;&lt;br /&gt;UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];&lt;br /&gt;UILabel *lblTemp2 = (UILabel *)[cell viewWithTag:2];&lt;br /&gt;&lt;br /&gt;if(searching) {&lt;br /&gt;&lt;br /&gt; lblTemp1.text = [copyListOfItems objectAtIndex:indexPath.row];&lt;br /&gt; lblTemp2.text = @"";&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt; //First get the dictionary object&lt;br /&gt; NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];&lt;br /&gt; NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt; NSString *cellValue = [array objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt; lblTemp1.text = cellValue;&lt;br /&gt; lblTemp2.text = @"Sub Value";&lt;br /&gt;&lt;br /&gt; [cellValue release];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;If you run this application now you will notice some obvious display issues, which we can resolve by specifying the height of the row. This is done in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:heightForRowAtIndexPath:"&gt;tableView:heightForRowAtIndexPath&lt;/a&gt; method. The code looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;return 60;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;All the rows in the table view will have a height of 60. Run your app to see the changes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;&lt;span class="fullpost"&gt;&lt;span style=""&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;In this tutorial we saw how easy it is to customize the table view cell. The same principle can be applied to customize the display by adding different controls to the content view. Instead of adding labels a progress bar can also be added. I hope this tutorial has helped you in some way.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/TableViewPart6.zip?attredirects=0"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html" uitableview="" indexed="" table="" view=""&gt;UITableView - Indexed table view&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;UITableView - Adding subviews to a cell's content view&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-5562533964127095331?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/gcWWiXrbzq0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/5562533964127095331/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=5562533964127095331&amp;isPopup=true" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/5562533964127095331" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/5562533964127095331" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/gcWWiXrbzq0/uitableview-adding-subviews-to-cells.html" title="UITableView - Adding subviews to a cell's content view" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_ixq8Dp4ESMo/SYuf0abKXEI/AAAAAAAAAEg/gPRseXSx8OA/s72-c/FinalApp.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-6338847876718763928</id><published>2009-01-24T15:42:00.030-05:00</published><updated>2009-02-10T21:06:33.612-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UIPickerView" /><title type="text">UIPickerView - Creating a simple picker view</title><content type="html">&lt;span class="previewpost"&gt;Apple provides a control knows as the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIPickerView_Class/index.html"&gt;UIPickerView&lt;/a&gt;, with which a user can select an item from a list. In this tutorial you will learn how to create a simple picker view. Click on "Read more..." to continue&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The picker view lets the user select an item from a list. In this tutorial, you will learn how easy it is to configure a picker view and respond to events. This is how the app will look like&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh5.ggpht.com/_ixq8Dp4ESMo/SYuYWJmpQaI/AAAAAAAAAD8/ihkIAiwOxSQ/s576/FinalApp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://lh5.ggpht.com/_ixq8Dp4ESMo/SYuYWJmpQaI/AAAAAAAAAD8/ihkIAiwOxSQ/s576/FinalApp.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating the project&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new project by selecting "Windows-Based Application", I have named my project "PickerView". I also added another view called "PickerView" and created a view controller for the view called "PickerViewController". Add a UIPickerView to the view and create all the right connections. The "PickerViewController" implements two protocols and this is how the header file looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface PickerViewController : UIViewController &amp;lt;UIPickerViewDataSource, UIPickerViewDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt;IBOutlet UIPickerView *pickerView;&lt;br /&gt;NSMutableArray *arrayColors;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The connections of the picker view looks like this&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ixq8Dp4ESMo/SZIyExK9_8I/AAAAAAAAAFo/P9aNqjYrEBw/s1600-h/Connections.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 289px; height: 145px;" src="http://1.bp.blogspot.com/_ixq8Dp4ESMo/SZIyExK9_8I/AAAAAAAAAFo/P9aNqjYrEBw/s320/Connections.jpg" alt="" id="BLOGGER_PHOTO_ID_5301354768868704194" border="0" /&gt;&lt;/a&gt;&lt;span class="fullpost"&gt;This is how the UIPickerView is added to the subview of the window.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;pvController = [[PickerViewController alloc] initWithNibName:@"PickerView" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt;[window addSubview:pvController.view];&lt;br /&gt;&lt;br /&gt;// Override point for customization after application launch&lt;br /&gt;[window makeKeyAndVisible];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Creating the data source&lt;br /&gt;&lt;/span&gt;Lets create a data source, with all the colors in a rainbow. The array is declared in the header file and released in the dealloc method. It is populated in viewDidLoad method and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//PickerViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;arrayColors = [[NSMutableArray alloc] init];&lt;br /&gt;[arrayColors addObject:@"Red"];&lt;br /&gt;[arrayColors addObject:@"Orange"];&lt;br /&gt;[arrayColors addObject:@"Yellow"];&lt;br /&gt;[arrayColors addObject:@"Green"];&lt;br /&gt;[arrayColors addObject:@"Blue"];&lt;br /&gt;[arrayColors addObject:@"Indigo"];&lt;br /&gt;[arrayColors addObject:@"Violet"];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The picker view can be divided into components, we need to specify how many components to display. This is done in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/iPhone/Reference/UIPickerViewDataSource_Protocol/Introduction/Introduction.html#//apple_ref/occ/intfm/UIPickerViewDataSource/numberOfComponentsInPickerView:"&gt;numberOfComponentsInPickerView&lt;/a&gt; method. This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//PickerViewController.m&lt;br /&gt;- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {&lt;br /&gt;&lt;br /&gt;return 1;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Now that the picker view knows how many components it should expect, we need to specify how many rows it should display. This is done in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/iPhone/Reference/UIPickerViewDataSource_Protocol/Introduction/Introduction.html#//apple_ref/occ/intfm/UIPickerViewDataSource/pickerView:numberOfRowsInComponent:"&gt;pickerView:numberOfRowsInComponent&lt;/a&gt;. This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//PickerViewController.m&lt;br /&gt;- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {&lt;br /&gt;&lt;br /&gt;return [arrayColors count];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIPickerViewDelegate_Protocol/Reference/UIPickerViewDelegate.html#//apple_ref/occ/intfm/UIPickerViewDelegate/pickerView:titleForRow:forComponent:"&gt;pickerView:titleForRow:forComponent&lt;/a&gt; gets called n number of times, where n is the number returned in pickerView:numberOfRowsInComponent. This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//PickerViewController.m&lt;br /&gt;- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {&lt;br /&gt;&lt;br /&gt;return [arrayColors objectAtIndex:row];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the above code, we return the object at index using the row parameter. Here we ignored the component parameter, as we only have one component to display. If you have more then one component, then we return the row present in that given component. Run your application to see the values in the picker view.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Handling Events&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The method &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIPickerViewDelegate_Protocol/Reference/UIPickerViewDelegate.html#//apple_ref/occ/intfm/UIPickerViewDelegate/pickerView:didSelectRow:inComponent:"&gt;pickerView:didSelectRow:inComponent&lt;/a&gt; is called when an item is selected in the picker view. In the example, I simply log the selected color and the row number. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//PickerViewController.m&lt;br /&gt;- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {&lt;br /&gt;&lt;br /&gt;NSLog(@"Selected Color: %@. Index of selected color: %i", [arrayColors objectAtIndex:row], row);&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;Picker view is a perfect control to display a list of items, from which one single item can be selected. In this tutorial, we saw how easy it is to configure a picker view and respond to events. I hope this tutorial has helped you in some little way. Stay tuned for some more tutorials on the UIPickerView object.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/UIPickerViewPart1.zip"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/search/label/UITableView"&gt;UITableView Tutorial Series&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-6338847876718763928?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/__nSWjflgtQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/6338847876718763928/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=6338847876718763928&amp;isPopup=true" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/6338847876718763928" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/6338847876718763928" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/__nSWjflgtQ/uipickerview-creating-simple-picker.html" title="UIPickerView - Creating a simple picker view" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_ixq8Dp4ESMo/SZIyExK9_8I/AAAAAAAAAFo/P9aNqjYrEBw/s72-c/Connections.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">14</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/01/uipickerview-creating-simple-picker.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-345822434433493651</id><published>2009-01-24T12:27:00.028-05:00</published><updated>2009-05-09T13:55:15.336-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Indexed table view</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial you will learn how to create a simple index for the table view. This index view shows up on the right side, just like the contacts application. Click on "Read more..." to learn more&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Indexed table view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;Displaying an index for the table view is another way for the users to get the data faster. This tutorial will show you how to do that. This is the fifth tutorial in the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/index.html"&gt;UITableView&lt;/a&gt; tutorial series and borrows its code from the previous one. This is how the app will look like&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgXDdMDGwvI/AAAAAAAAAHw/BPV464tvu0E/s1600-h/FinalApp.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 166px; height: 320px;" src="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgXDdMDGwvI/AAAAAAAAAHw/BPV464tvu0E/s320/FinalApp.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5333884239908094706" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Creating an Index&lt;/span&gt;&lt;br /&gt;The first thing we need to do is create an array, which will contain the index values to display. The values in the array has to be of type &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/NSString_UIKit_Additions/index.html"&gt;NSString&lt;/a&gt;. The Apple documentation says that the style of the table view should be set to &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableViewStyle"&gt;UITableViewStylePlain&lt;/a&gt;. However, it does not throw an error when the style is set to &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableViewStyle"&gt;UITableViewStyleGrouped&lt;/a&gt;. The array is returned in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/sectionIndexTitlesForTableView:"&gt;sectionIndexTitlesForTableView&lt;/a&gt; method and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {&lt;br /&gt;&lt;br /&gt;if(searching)&lt;br /&gt;return nil;&lt;br /&gt;&lt;br /&gt;NSMutableArray *tempArray = [[NSMutableArray alloc] init];&lt;br /&gt;[tempArray addObject:@"1"];&lt;br /&gt;[tempArray addObject:@"2"];&lt;br /&gt;[tempArray addObject:@"3"];&lt;br /&gt;[tempArray addObject:@"4"];&lt;br /&gt;[tempArray addObject:@"5"];&lt;br /&gt;[tempArray addObject:@"6"];&lt;br /&gt;[tempArray addObject:@"7"];&lt;br /&gt;[tempArray addObject:@"8"];&lt;br /&gt;[tempArray addObject:@"9"];&lt;br /&gt;[tempArray addObject:@"10"];&lt;br /&gt;[tempArray addObject:@"11"];&lt;br /&gt;[tempArray addObject:@"12"];&lt;br /&gt;[tempArray addObject:@"13"];&lt;br /&gt;[tempArray addObject:@"14"];&lt;br /&gt;[tempArray addObject:@"15"];&lt;br /&gt;[tempArray addObject:@"16"];&lt;br /&gt;[tempArray addObject:@"17"];&lt;br /&gt;[tempArray addObject:@"18"];&lt;br /&gt;[tempArray addObject:@"19"];&lt;br /&gt;[tempArray addObject:@"20"];&lt;br /&gt;[tempArray addObject:@"21"];&lt;br /&gt;[tempArray addObject:@"22"];&lt;br /&gt;[tempArray addObject:@"23"];&lt;br /&gt;[tempArray addObject:@"24"];&lt;br /&gt;[tempArray addObject:@"25"];&lt;br /&gt;[tempArray addObject:@"26"];&lt;br /&gt;&lt;br /&gt;return tempArray;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The above code creates an array and returns it. You can populate this array with alphabets from 'A' to 'Z'. If the user is searching the table view, then the array is not returned. This way the index view is not shown.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Handling Events&lt;/span&gt;&lt;br /&gt;When an item in the index is clicked, the section starting with the selected index item is displayed. The event that gets called is &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:sectionForSectionIndexTitle:atIndex:"&gt;tableView:sectionForSectionIndexTitle:atIndex&lt;/a&gt;, which returns an index of the section to display. Since our data source only has two sections and 26 index values, the code looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {&lt;br /&gt;&lt;br /&gt;if(searching)&lt;br /&gt;return -1;&lt;br /&gt;&lt;br /&gt;return index % 2;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;If the user is searching the table view, then we do not return the index of the section. The data source is changed a little to include some test objects, so the section selection is obvious. Since the index shows up very close to the accessory view, the accessory view is set to &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableViewCellAccessoryType"&gt;UITableViewCellAccessoryNone&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Just by implementing two methods, we have created an index for the table view. However, I think Apple has kept some methods private. Since we cannot display the magnifying glass like the contacts application. If you have an idea on how to get it working, please let us know.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/TableViewPart5.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Indexed table view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-345822434433493651?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/tSWRRcfdzkk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/345822434433493651/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=345822434433493651&amp;isPopup=true" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/345822434433493651" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/345822434433493651" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/tSWRRcfdzkk/uitableview-indexed-table-view.html" title="UITableView - Indexed table view" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgXDdMDGwvI/AAAAAAAAAHw/BPV464tvu0E/s72-c/FinalApp.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-629903812205104361</id><published>2009-01-18T18:23:00.039-05:00</published><updated>2009-02-13T00:07:56.275-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Searching table view</title><content type="html">&lt;span class="previewpost"&gt;If the user has to scroll often to get to access the data, providing a search bar to search the table view helps in making the process faster. To learn more on searching, click on "Read more"...&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned Table View&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Searching table view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Introduction&lt;/span&gt;&lt;br /&gt;In this tutorial, you will learn how to search the contents of the table view. This is the fourth tutorial in the UITableView tutorial series and borrows its code from the previous one. This is how the final app looks like&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh6.ggpht.com/_ixq8Dp4ESMo/SYugD2Pnl9I/AAAAAAAAAEw/nzI3VbLlzVc/s576/SearchView.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://lh6.ggpht.com/_ixq8Dp4ESMo/SYugD2Pnl9I/AAAAAAAAAEw/nzI3VbLlzVc/s576/SearchView.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Adding the search bar&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Let's get started by adding the search bar to our existing sectioned table view app. Open Interface Builder by double clicking "RootViewController.nib" file. Drag and drop a &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UISearchBar_Class/index.html" target="_blank"&gt;UISearchBar&lt;/a&gt; object in the nib file. In XCode, open RootViewController.h file declare a variable of type UISearchBar called "searchBar" and declare it with the keyword "IBoutlet" so it is visible in IB. Connect the variable to the UISearchBar object and set the delegate of UISearchBar to File's Owner. This way the "RootViewController" gets notified of all the events generated on the search bar. This is how the header file looks like, where I have added some more variables and method which will help us in searching.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.h&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;NSMutableArray *listOfItems;&lt;br /&gt;  NSMutableArray *copyListOfItems;&lt;br /&gt;IBOutlet UISearchBar *searchBar;&lt;br /&gt;BOOL searching;&lt;br /&gt;BOOL letUserSelectRow;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) searchTableView;&lt;br /&gt;- (void) doneSearching_Clicked:(id)sender;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The search bar is added to the header of the table view in "viewDidLoad" method and this how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;//Initialize the array.&lt;br /&gt;listOfItems = [[NSMutableArray alloc] init];&lt;br /&gt;&lt;br /&gt;NSArray *countriesToLiveInArray = [NSArray arrayWithObjects:@"Iceland", @"Greenland", @"Switzerland", @"Norway", @"New Zealand", @"Greece", @"Rome", @"Ireland", nil];&lt;br /&gt;NSDictionary *countriesToLiveInDict = [NSDictionary dictionaryWithObject:countriesToLiveInArray forKey:@"Countries"];&lt;br /&gt;&lt;br /&gt;NSArray *countriesLivedInArray = [NSArray arrayWithObjects:@"India", @"U.S.A", nil];&lt;br /&gt;NSDictionary *countriesLivedInDict = [NSDictionary dictionaryWithObject:countriesLivedInArray forKey:@"Countries"];&lt;br /&gt;&lt;br /&gt;[listOfItems addObject:countriesToLiveInDict];&lt;br /&gt;[listOfItems addObject:countriesLivedInDict];&lt;br /&gt;&lt;br /&gt;//Initialize the copy array.&lt;br /&gt;copyListOfItems = [[NSMutableArray alloc] init];&lt;br /&gt;&lt;br /&gt;//Set the title&lt;br /&gt;self.navigationItem.title = @"Countries";&lt;br /&gt;&lt;br /&gt;//Add the search bar&lt;br /&gt;self.tableView.tableHeaderView = searchBar;&lt;br /&gt;searchBar.autocorrectionType = UITextAutocorrectionTypeNo;&lt;br /&gt;&lt;br /&gt;searching = NO;&lt;br /&gt;letUserSelectRow = YES;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Here we also set some boolean variables which will help us in searching. More about this later in the tutorial. The search bar is added to the "tableHeaderView" property of the table view. I also have another mutable array called "copyListOfItems", which is used to store the search results. It used as the data source of the table view when searching. Run your application to see the search bar added to the top of the table view. The search bar is also released in the dealloc method (source code not provided here).&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;How the search will work&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Before we proceed with any code, lets review some things we will do. When the user begins searching by clicking the search text box, we will do the following:&lt;ol&gt;&lt;li&gt;Set the "searching" variable to YES.&lt;/li&gt;&lt;li&gt;Set the "letUserSelectRow" variable to NO, since we do not want the user to select a row when the search box is empty.&lt;/li&gt;&lt;li&gt;Disable scrolling of the table view. This is done to avoid an error that is raised, when the user scrolls the table view after the search bar is clicked.&lt;/li&gt;&lt;li&gt;Display a done button on the right bar.&lt;/li&gt;&lt;li&gt;Start searching as the user starts typing, this time allowing the user to select a row.&lt;/li&gt;&lt;li&gt;Use a different data source to bind the table, which display's the search reults.&lt;/li&gt;&lt;li&gt;Search results are displayed in a single list and they are not grouped.&lt;/li&gt;&lt;li&gt;Hide the keyboard and finish searching, when the user clicks on done.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Handling events&lt;/span&gt;&lt;br /&gt;The first event that gets raised, is when the user touches the search bar to bring up the keyboard. The method &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UISearchBarDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UISearchBarDelegate/searchBarTextDidBeginEditing:" target="_blank"&gt;searchBarTextDidBeginEditing&lt;/a&gt; is called and this is where we set the table view in search mode. The code looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {&lt;br /&gt;&lt;br /&gt;searching = YES;&lt;br /&gt;letUserSelectRow = NO;&lt;br /&gt;self.tableView.scrollEnabled = NO;&lt;br /&gt;&lt;br /&gt;//Add the done button.&lt;br /&gt;self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]&lt;br /&gt;           initWithBarButtonSystemItem:UIBarButtonSystemItemDone&lt;br /&gt;           target:self action:@selector(doneSearching_Clicked:)] autorelease];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Set the "searching" variable to YES, so we know the table view is in search mode. The variable "letUserSelectRow" is set to NO, so we can prohibit the user from selecting a row. Scrolling of the table view is also disabled which will help us when we add a overlay above the view. This is done in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:willSelectRowAtIndexPath:" target="_blank"&gt;tableView:willSelectRowAtIndexPath&lt;/a&gt; method and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;if(letUserSelectRow)&lt;br /&gt;return indexPath;&lt;br /&gt;else&lt;br /&gt;return nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The above code prevents the user from selecting a row if the variable "letUserSelectRow" is set to true.&lt;br /&gt;&lt;br /&gt;The method "doneSearching_Clicked" is called when the user clicks the done method. The code for this method is shown later in this tutorial.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Searching the table view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The method &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UISearchBarDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UISearchBarDelegate/searchBar:textDidChange:" target="_blank"&gt;searchBar:textDidChange&lt;/a&gt; is called when the user starts typing in the search field. This is how the search code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {&lt;br /&gt;&lt;br /&gt;//Remove all objects first.&lt;br /&gt;[copyListOfItems removeAllObjects];&lt;br /&gt;&lt;br /&gt;if([searchText length] &gt; 0) {&lt;br /&gt;&lt;br /&gt;searching = YES;&lt;br /&gt;letUserSelectRow = YES;&lt;br /&gt;self.tableView.scrollEnabled = YES;&lt;br /&gt;[self searchTableView];&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;searching = NO;&lt;br /&gt;letUserSelectRow = NO;&lt;br /&gt;self.tableView.scrollEnabled = NO;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[self.tableView reloadData];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;There is a lot of stuff going on in the code above, so let's look at it line by line&lt;ol&gt;&lt;li&gt;We first empty the array, which is used as the data source to the table view when searching.&lt;/li&gt;&lt;li&gt;If the search bar has some text then we continue searching, by calling "searchTableView" method. This time we let the user select a row to see its detail view.&lt;/li&gt;&lt;li&gt;The method "searchTableView" is responsible to search the table view based on the search text and populate the search results in the array "copyListOfItems".&lt;/li&gt;&lt;li&gt;If the search bar is empty then, disable scrolling, set the searching variable to NO, and prohibit the user from selecting a row. &lt;/li&gt;&lt;li&gt;At last we refresh the table view.&lt;/li&gt;&lt;/ol&gt;Before we jump to understand how the table view is able to display the search results, let's review what happens when the user clicks the search button and the "searchTableView" method.&lt;br /&gt;&lt;br /&gt;The method "&lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UISearchBarDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UISearchBarDelegate/searchBarSearchButtonClicked:" target="_blank"&gt;searchBarSearchButtonClicked&lt;/a&gt;" is called and this is how the code looks like, where we simply call "searchTableView" method.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {&lt;br /&gt;&lt;br /&gt;[self searchTableView];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) searchTableView {&lt;br /&gt;&lt;br /&gt;NSString *searchText = searchBar.text;&lt;br /&gt;NSMutableArray *searchArray = [[NSMutableArray alloc] init];&lt;br /&gt;&lt;br /&gt;for (NSDictionary *dictionary in listOfItems)&lt;br /&gt;{&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;[searchArray addObjectsFromArray:array];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;for (NSString *sTemp in searchArray)&lt;br /&gt;{&lt;br /&gt;NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];&lt;br /&gt;&lt;br /&gt;if (titleResultsRange.length &gt; 0)&lt;br /&gt;[copyListOfItems addObject:sTemp];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[searchArray release];&lt;br /&gt;searchArray = nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's review what goes on in "searchTableView" method. We first create a temporary search array, which we will fill it all the objects from the original data source. We loop through the dictionary objects, and add all the array objects to "searchArray". We then loop through all the items in "searchArray" and compare it with the search text. We add the string object to the "copyListOfItems" if we find the search text in one of the countries.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Finish Searching&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The following method "doneSearching_Clicked" is called when the user clicks the done button and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void) doneSearching_Clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;searchBar.text = @"";&lt;br /&gt;[searchBar resignFirstResponder];&lt;br /&gt;&lt;br /&gt;letUserSelectRow = YES;&lt;br /&gt;searching = NO;&lt;br /&gt;self.navigationItem.rightBarButtonItem = nil;&lt;br /&gt;self.tableView.scrollEnabled = YES;&lt;br /&gt;&lt;br /&gt;[self.tableView reloadData];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We hide the keyboard, let the user select a row, set "searching" to false and hide the right bar button item.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Displaying search results&lt;/span&gt;&lt;br /&gt;The search results are stored in "copyListOfItems" array and the table view is refreshed by calling &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/reloadData" target="_blank"&gt;reloadData&lt;/a&gt;. We also set the variable "searching" to YES when the user is searching, so we know to display the search results. To display results results we have to change few methods. The code changes for the following methods "&lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/numberOfSectionsInTableView:" target="_blank"&gt;numberOfSectionsInTableView&lt;/a&gt;", "&lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:" target="_blank"&gt;tableView:numberOfRowsInSection&lt;/a&gt;", "&lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:titleForHeaderInSection:" target="_blank"&gt;tableView:titleForHeaderInSection&lt;/a&gt;", "&lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:cellForRowAtIndexPath:" target="_blank"&gt;tableView:cellForRowAtIndexPath&lt;/a&gt;", and "&lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:" target="_blank"&gt;tableView:didSelectRowAtIndexPath&lt;/a&gt;". We have to display data from "copyListOfItems" is the variable "searching" is set to YES else we display data as before. Let's look at the code of all these methods&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {&lt;br /&gt;&lt;br /&gt;if (searching)&lt;br /&gt;return 1;&lt;br /&gt;else&lt;br /&gt;return [listOfItems count];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Customize the number of rows in the table view.&lt;br /&gt;- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {&lt;br /&gt;&lt;br /&gt;if (searching)&lt;br /&gt;return [copyListOfItems count];&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;//Number of rows it should expect should be based on the section&lt;br /&gt;NSDictionary *dictionary = [listOfItems objectAtIndex:section];&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;return [array count];&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {&lt;br /&gt;&lt;br /&gt;if(searching)&lt;br /&gt;return @"";&lt;br /&gt;&lt;br /&gt;if(section == 0)&lt;br /&gt;return @"Countries to visit";&lt;br /&gt;else&lt;br /&gt;return @"Countries visited";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Customize the appearance of table view cells.&lt;br /&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;  cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Set up the cell...&lt;br /&gt;&lt;br /&gt;if(searching)&lt;br /&gt;cell.text = [copyListOfItems objectAtIndex:indexPath.row];&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;//First get the dictionary object&lt;br /&gt;NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;NSString *cellValue = [array objectAtIndex:indexPath.row];&lt;br /&gt;cell.text = cellValue;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//Get the selected country&lt;br /&gt;&lt;br /&gt;NSString *selectedCountry = nil;&lt;br /&gt;&lt;br /&gt;if(searching)&lt;br /&gt;selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;selectedCountry = [array objectAtIndex:indexPath.row];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Initialize the detail view controller and display it.&lt;br /&gt;DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;dvController.selectedCountry = selectedCountry;&lt;br /&gt;[self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;[dvController release];&lt;br /&gt;dvController = nil;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In "numberOfSectionsInTableView" we return 1 if we are searching because the search results are not displayed in sections. In tableView:numberOfRowsInSection we return the count of the search results array, if we are searching. We return the text "Search Results" when searching in tableView:titleForHeaderInSection method. We get the data from the search results array when displaying text in tableView:cellForRowAtIndexPath method. The same logic is used to get the selected country in tableView:didSelectRowAtIndexPath method.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Adding an overlay&lt;/span&gt;&lt;br /&gt;If you do a search in the contacts application, the table view gets a gray overlay above the table view and the search is canceled if the user touches the table view. We can do this same, by adding an overlay view above the table view.&lt;br /&gt;&lt;br /&gt;Let's adding another view under resource and name it "OverlayView". Create a view controller called "OverlayViewController" in XCode. Open the nib file in IB and set the class of File's Owner to "OverlayViewController" and create all the appropriate connections. Make sure that the view is able to respond to touches.&lt;br /&gt;&lt;br /&gt;Now let's add the overlay above the table view. We do this in "searchBarTextDidBeginEditing" and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {&lt;br /&gt;&lt;br /&gt;//Add the overlay view.&lt;br /&gt;if(ovController == nil)&lt;br /&gt;ovController = [[OverlayViewController alloc] initWithNibName:@"OverlayView" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt;CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;&lt;br /&gt;CGFloat width = self.view.frame.size.width;&lt;br /&gt;CGFloat height = self.view.frame.size.height;&lt;br /&gt;&lt;br /&gt;//Parameters x = origion on x-axis, y = origon on y-axis.&lt;br /&gt;CGRect frame = CGRectMake(0, yaxis, width, height);&lt;br /&gt;ovController.view.frame = frame;&lt;br /&gt;ovController.view.backgroundColor = [UIColor grayColor];&lt;br /&gt;ovController.view.alpha = 0.5;&lt;br /&gt;&lt;br /&gt;ovController.rvController = self;&lt;br /&gt;&lt;br /&gt;[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];&lt;br /&gt;&lt;br /&gt;searching = YES;&lt;br /&gt;letUserSelectRow = NO;&lt;br /&gt;self.tableView.scrollEnabled = NO;&lt;br /&gt;&lt;br /&gt;//Add the done button.&lt;br /&gt;self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]&lt;br /&gt;           initWithBarButtonSystemItem:UIBarButtonSystemItemDone&lt;br /&gt;           target:self action:@selector(doneSearching_Clicked:)] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We have changed the header file "RootViewController.h" to add a variable "ovController" of type "OverLayViewController" and the header file is added to the top of RootViewController.m file.&lt;br /&gt;&lt;br /&gt;Start by initializing the overlay view controller with the nib name "OverlayView". We perform some calculations to find out where the search bar ends, as we want the overlay view to show up below the search bar. We set the &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instp/UIView/frame" target="_blank"&gt;frame&lt;/a&gt; of the view which will redraw the view on the screen. We set the background color and its transparency. The next line of code says that the self is assigned to the "rvController" property. The view is inserted above the table view, using insertSubView method.&lt;br /&gt;&lt;br /&gt;We have declared a variable called "rvController" of type "RootViewController" in "OverlayViewController". The reason it is done because, we want a reference to the root view controller from the overlay controller. This is how the header file and implementation file of the "OverlayController" looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//OverlayViewController.h&lt;br /&gt;@class RootViewController;&lt;br /&gt;&lt;br /&gt;@interface OverlayViewController : UIViewController {&lt;br /&gt;&lt;br /&gt;RootViewController *rvController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) RootViewController *rvController;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;//OverlayViewController.m&lt;br /&gt;#import "OverlayViewController.h"&lt;br /&gt;#import "RootViewController.h"&lt;br /&gt;&lt;br /&gt;@implementation OverlayViewController&lt;br /&gt;&lt;br /&gt;@synthesize rvController;&lt;br /&gt;&lt;br /&gt;- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {&lt;br /&gt; &lt;br /&gt; [rvController doneSearching_Clicked:nil];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void)didReceiveMemoryWarning {&lt;br /&gt;[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview&lt;br /&gt;// Release anything that's not essential, such as cached data&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- (void)dealloc {&lt;br /&gt;[rvController release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's look at the method &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/touchesBegan:withEvent:" target="_blank"&gt;touchesBegan:withEvent&lt;/a&gt; which is called when the user touches the overlay view. A call is made to the "doneSearching_Clicked" method defined in "RootViewController". This is possible because we have a reference to the root view controller.&lt;br /&gt;&lt;br /&gt;Now that that a overlay shows up when the user clicks the search bar, it should be hidden when the user starts searching. The method searchBar:textDidChange method now changes accordingly&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {&lt;br /&gt;&lt;br /&gt;//Remove all objects first.&lt;br /&gt;[copyListOfItems removeAllObjects];&lt;br /&gt;&lt;br /&gt;if([searchText length] &gt; 0) {&lt;br /&gt;&lt;br /&gt;[ovController.view removeFromSuperview];&lt;br /&gt;searching = YES;&lt;br /&gt;letUserSelectRow = YES;&lt;br /&gt;self.tableView.scrollEnabled = YES;&lt;br /&gt;[self searchTableView];&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&lt;br /&gt;[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];&lt;br /&gt;&lt;br /&gt;searching = NO;&lt;br /&gt;letUserSelectRow = NO;&lt;br /&gt;self.tableView.scrollEnabled = NO;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[self.tableView reloadData];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We remove the view if the user starts searching and add it back if the search bar is empty. The overlay view is removed and released when the user clicks the done button. This is how the code for "doneSearching_Clicked" is changed&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void) doneSearching_Clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;searchBar.text = @"";&lt;br /&gt;[searchBar resignFirstResponder];&lt;br /&gt;&lt;br /&gt;letUserSelectRow = YES;&lt;br /&gt;searching = NO;&lt;br /&gt;self.navigationItem.rightBarButtonItem = nil;&lt;br /&gt;self.tableView.scrollEnabled = YES;&lt;br /&gt;&lt;br /&gt;[ovController.view removeFromSuperview];&lt;br /&gt;[ovController release];&lt;br /&gt;ovController = nil;&lt;br /&gt;&lt;br /&gt;[self.tableView reloadData];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The overlay is removed, released and set to nil. Run the app to see the search work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;Providing a search feature to the table view is a good option, if the user has to scroll a lot to select a row. I hope you had fun reading this tutorial as much as I had writing it. Don't forget to leave a comment.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/TableViewPart4.zip?attredirects=0"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned Table View&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Searching table view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-629903812205104361?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/gq79aG4A3hc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/629903812205104361/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=629903812205104361&amp;isPopup=true" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/629903812205104361" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/629903812205104361" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/gq79aG4A3hc/uitableview-searching-table-view.html" title="UITableView - Searching table view" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_ixq8Dp4ESMo/SYugD2Pnl9I/AAAAAAAAAEw/nzI3VbLlzVc/s72-c/SearchView.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-6069153997434366724</id><published>2009-01-18T17:24:00.022-05:00</published><updated>2009-05-09T13:46:01.952-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Sectioned Table View</title><content type="html">&lt;span class="previewpost"&gt;Sometimes it makes sense to group information and show it to the user. In this tutorial, you will learn how to create a simple sectioned table view. Click on "Read more" to learn more...&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Sectioned Table View&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;So far we have seen how easy it is to display list of items in a table view. As it turns out, displaying grouped items is easy too. This is the third tutorial in the UITableView tutorial series and it borrows its source code from the previous one. This is how the final app will look like&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgXBSogID6I/AAAAAAAAAHo/aFfW9E65xoE/s1600-h/FinalApp.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 166px; height: 320px;" src="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgXBSogID6I/AAAAAAAAAHo/aFfW9E65xoE/s320/FinalApp.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5333881859544190882" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Preparing the Data Source&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;From the above picture it is obvious that the countries are grouped into two sections: "Countries to visit" and "Countries visited". I don't know where I want to go next but Iceland is been on my list for a long time :).&lt;br /&gt;&lt;br /&gt;Since the information is now grouped, we need to create our data source in a specific way, which will make it easier to display the data. We will still use a NSMutableArray to hold the data. This time we will populate it with two &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html" target="_blank"&gt;dictionary&lt;/a&gt; objects, instead of simple strings. The dictionary objects will contain one key/value pair, where the key will be a string and the value will be an array containing all the countries. This is done in viewDidLoad method and this is how the method changes from the second tutorial&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;//Initialize the array.&lt;br /&gt;listOfItems = [[NSMutableArray alloc] init];&lt;br /&gt;&lt;br /&gt;NSArray *countriesToLiveInArray = [NSArray arrayWithObjects:@"Iceland", @"Greenland", @"Switzerland", @"Norway", @"New Zealand", @"Greece", @"Rome", @"Ireland", nil];&lt;br /&gt;NSDictionary *countriesToLiveInDict = [NSDictionary dictionaryWithObject:countriesToLiveInArray forKey:@"Countries"];&lt;br /&gt;&lt;br /&gt;NSArray *countriesLivedInArray = [NSArray arrayWithObjects:@"India", @"U.S.A", nil];&lt;br /&gt;NSDictionary *countriesLivedInDict = [NSDictionary dictionaryWithObject:countriesLivedInArray forKey:@"Countries"];&lt;br /&gt;&lt;br /&gt;[listOfItems addObject:countriesToLiveInDict];&lt;br /&gt;[listOfItems addObject:countriesLivedInDict];&lt;br /&gt;&lt;br /&gt;//Set the title&lt;br /&gt;self.navigationItem.title = @"Countries";&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;P.S The array is declared in the header file and released in the dealloc method, this is shown in the first part of the tutorial. It also contains information about the detail view.&lt;br /&gt;&lt;br /&gt;We create two arrays: countries to visit and countries visited. The arrays are then used to create dictionary objects with the key "Countries" and they are added to the "listOfItems" array with countries to live followed by countries lived in.&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;br /&gt;Preparing UITableView to display data&lt;/span&gt;&lt;br /&gt;The table view needs to know how many sections it should expect, which is the number returned in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/numberOfSectionsInTableView:" target="_blank"&gt;numberOfSectionsInTableView&lt;/a&gt; method. Since we only have two dictionary objects added to the array, it know to display two sections. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {&lt;br /&gt;&lt;br /&gt;return [listOfItems count];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The table view needs to know how many rows it should expect it in every section, which is the number returned in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:" target="_blank"&gt;tableView:numberOfRowsInSection&lt;/a&gt; method. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;// Customize the number of rows in the table view.&lt;br /&gt;- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {&lt;br /&gt;&lt;br /&gt;//Number of rows it should expect should be based on the section&lt;br /&gt;NSDictionary *dictionary = [listOfItems objectAtIndex:section];&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;return [array count];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We have added two dictionary objects in the array, so this method will be called twice. Since the index of the section and the array starts with 0, We can use this to get the dictionary located at a specific index. Once we find out which dictionary the table view is displaying, we get the array using the key "Countries" and return the count of the array.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Displaying the header text&lt;/span&gt;&lt;br /&gt;We took care of the number of sections and the rows the table view should know about. We still have to display the actual header text that shows up in the table view. This is done in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:titleForHeaderInSection:" target="_blank"&gt;tableView:titleForHeaderInSection&lt;/a&gt; method which is called twice since we only have two groups. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {&lt;br /&gt;&lt;br /&gt;if(section == 0)&lt;br /&gt;return @"Countries to visit";&lt;br /&gt;else&lt;br /&gt;return @"Countries visited";&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We know that the first dictionary in "listOfItems" array contains the list of countries I want to visit. So the above code checks if the section is 0 or not and displays the relevant header text.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Displaying the text of the UITableViewCell&lt;/span&gt;&lt;br /&gt;We now have the header text but what about the text of the cell. The logic is similar to that of &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:" target="_blank"&gt;tableView:numberOfRowsInSection&lt;/a&gt;. We first find out which dictionary object we should read, from the section property of &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/NSIndexPath_UIKitAdditions/index.html" target="blank"&gt;NSIndexPath&lt;/a&gt;. We then get the dictionary object, with its array from the key "Countries". At last we display the text of the cell by getting the string at a given row, which comes from the row property of NSIndexPath. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Set up the cell...&lt;br /&gt;&lt;br /&gt;//First get the dictionary object&lt;br /&gt;NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;NSString *cellValue = [array objectAtIndex:indexPath.row];&lt;br /&gt;cell.text = cellValue;&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Selecting the right row&lt;/span&gt;&lt;br /&gt;The method &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:" target="_blank"&gt;tableView:didSelectRowAtIndexPath&lt;/a&gt; also changes, to adjust the sectioned table view. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//Get the selected country&lt;br /&gt;&lt;br /&gt;NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];&lt;br /&gt;NSArray *array = [dictionary objectForKey:@"Countries"];&lt;br /&gt;NSString *selectedCountry = [array objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Initialize the detail view controller and display it.&lt;br /&gt;DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;dvController.selectedCountry = selectedCountry;&lt;br /&gt;[self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;[dvController release];&lt;br /&gt;dvController = nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The code is similar to tableView:cellForRowAtIndexPath, in how we access the dictionary, array, and the selected country value.&lt;br /&gt;&lt;br /&gt;Run your application to see the sectioned table view in action.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Setting the style of UITableView&lt;/span&gt;&lt;br /&gt;If your app looks like the picture above, then the &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableView/style" target="_blank"&gt;style&lt;/a&gt; of the table view is set to "Plan" in Interface Builder. Change this to "Grouped" and see how the display changes when you run the app.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;We have seen how we can display some information which is grouped together. I hope this tutorial was helpful to you and please leave your comments. My next tutorial will show you how to search the UITableView using the UISearchBar control.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/TableViewPart3.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Sectioned Table View&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-6069153997434366724?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/u-YP5u6q0fY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/6069153997434366724/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=6069153997434366724&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/6069153997434366724" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/6069153997434366724" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/u-YP5u6q0fY/uitableview-sectioned-table-view.html" title="UITableView - Sectioned Table View" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgXBSogID6I/AAAAAAAAAHo/aFfW9E65xoE/s72-c/FinalApp.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-8208857347384507847</id><published>2009-01-17T17:30:00.023-05:00</published><updated>2009-02-03T21:06:21.984-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Loading a detail view</title><content type="html">&lt;span class="previewpost"&gt;The purpose of a UITableView is to display a list of items, from which a user can select one item to see it's detail view. The navigation that happens between the table view and the detail view is controlled by the navigation controller. In this tutorial we will see how to navigate to a detail view.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Loading a detail view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned Table View&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;In this tutorial, you will learn how to navigate to the detail view and also pass some data at the same time. This is the second tutorial in the UITableView tutorial series and inherits its source code from the first tutorial.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating a detail view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Open Interface Builder and click on File -&gt; New -&gt; (select Cocoa Touch) View, save it in the application directory and name it "DetailView". You will be asked to add the view to the current project, click on "Add". You may need to drag the view (in XCode) to the "Resources" folder. Now that you have your view, we will create a view controller class to control the view on the screen. In XCode select Classes then click on File -&gt; New File -&gt; (under iPhone OS) select UIViewController subclass and name it "DetailViewController, do not change the extension. Now we have to connect the view to the view controller we just created. In Interface Builder, select File's Owner and open Identity Inspector, under class Identity set the class to "DetailViewController", open Connections Inspector and create a connection from the view property to the view object in the nib file.&lt;br /&gt;&lt;br /&gt;Now add controls to the view which will display the detail contents. The controls that you may want to add to the view, depends on the data you want to display. We will display the country selected in the table view, so a simple label should do. Drag and drop the label on the view. We need some way to change the text of the label from XCode, create a variable of type &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UILabel_Class/index.html" target="_blank"&gt;UILabel&lt;/a&gt; in xcode and connect it with the label object on the view. The label should be declared with IBOutlet property, so it shows up in the Connections Inspector. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface DetailViewController : UIViewController {&lt;br /&gt;&lt;br /&gt;IBOutlet UILabel *lblText;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;//Dealloc method declared in DetailViewController.m&lt;br /&gt;- (void)dealloc {&lt;br /&gt;&lt;br /&gt;[lblText release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;After you have declared the variable, open IB and connect the variable to the label placed on the view in Connections Inspector. Now we can change the label's properties from XCode.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Navigate to the detail view&lt;/span&gt;&lt;br /&gt;The method &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:" target="_blank"&gt;tableView:didSelectRowAtIndexPath&lt;/a&gt; is called when a row is selected, it passes the tableview object with the indexPath object to tell us which row was selected. First import the "DetailViewController" class in RootViewController, so it knows about it. The following code will initialize the detail view and display it&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;[self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;[dvController release];&lt;br /&gt;dvController = nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;A "DetailViewController" is created, initialized with &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/initWithNibName:bundle:" target="_blank"&gt;initWithNibName:bundle&lt;/a&gt; message and the name of the nib file is passed as the parameter. The view controller is then push to the top of the stack with its animated property set to YES. At last, we clean up memory by releasing the detail view controller. Run the application and now you can select a row to see the detail view.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Passing data&lt;/span&gt;&lt;br /&gt;We still have to pass the selected country from the list to the detail view. To do this, we will declare a property in "DetailViewController" whose data type is the same as the in the array, in our case NSString. This is what you have to do if you want to pass data from one view controller to another. The following code declares a property in "DetailViewController"&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//DetailViewController.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface DetailViewController : UIViewController {&lt;br /&gt;&lt;br /&gt;IBOutlet UILabel *lblText;&lt;br /&gt;NSString *selectedCountry;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSString *selectedCountry;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;//Dealloc method declared in DetailViewController.m&lt;br /&gt;- (void)dealloc {&lt;br /&gt;&lt;br /&gt;[selectedCountry release];&lt;br /&gt;[lblText release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//First three lines of DetailViewController.m&lt;br /&gt;#import "DetailViewController.h"&lt;br /&gt;&lt;br /&gt;@implementation DetailViewController&lt;br /&gt;&lt;br /&gt;@synthesize selectedCountry;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The property is synthesized at the top after the implementation begins. Now we can pass the selected country from the table view to the detail view. The tableView:didSelectRowAtIndexPath method looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//Get the selected country&lt;br /&gt;NSString *selectedCountry = [listOfItems objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Initialize the detail view controller and display it.&lt;br /&gt;DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];&lt;br /&gt;dvController.selectedCountry = selectedCountry;&lt;br /&gt;[self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;[dvController release];&lt;br /&gt;dvController = nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We first get the selected country from the array, initialize the detail view controller, set the selected country to the property on the detail view controller and display it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Setting the accessory view&lt;/span&gt;&lt;br /&gt;Run the app and now we are able to select a row in a table view. However, it is not obvious to the user that a row can be selected to see its detail view. We can add a "accessory view" to the cell which will show up at the right end of the row. The accessory view can be set up in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:cellForRowAtIndexPath:" target="_blank"&gt;tableView:cellForRowAtIndexPath&lt;/a&gt; method or in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:accessoryTypeForRowWithIndexPath:" target="_blank"&gt;tableView:accessoryTypeForRowWithIndexPath&lt;/a&gt;. We will use the later method to keep our code simple. This is how the source code changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;//return UITableViewCellAccessoryDetailDisclosureButton;&lt;br /&gt;return UITableViewCellAccessoryDisclosureIndicator;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The above method returns an enum &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableViewCellAccessoryType" target="_blank"&gt;UITableViewCellAccessoryType&lt;/a&gt; and we can return four values: UITableViewCellAccessoryNone, UITableViewCellAccessoryDisclosureIndicator, UITableViewCellAccessoryDetailDisclosureButton, and UITableViewCellAccessoryCheckmark. You can test the code by returning one of the four values to see how the accessory view looks like. If you return "UITableViewCellAccessoryDetailDisclosureButton" clicking on the button will not do anything, since the cell is not selected but a button is clicked. The SDK does provide a method which gets called when the accessory button is clicked and that is called &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:accessoryButtonTappedForRowWithIndexPath:" target="_blank"&gt;tableView:accessoryButtonTappedForRowWithIndexPath&lt;/a&gt;. In this method we can call &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:" target="_blank"&gt;tableView:didSelectRowAtIndexPath&lt;/a&gt; which will load the detail view and this is how the code will look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;[self tableView:tableView didSelectRowAtIndexPath:indexPath];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The last thing we need to do in detail view controller, is to display the selected country on the label. Do it in viewDidLoad method and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;// DetailViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;//Display the selected country.&lt;br /&gt;lblText.text = selectedCountry;&lt;br /&gt;&lt;br /&gt;//Set the title of the navigation bar&lt;br /&gt;self.navigationItem.title = @"Selected Country";&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method "viewDidLoad" gets called when the view is loaded, where we set the selected country by setting the text property of the label "lblText". The title of the navigation bar is also set in the same method.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We have seen how to display a list of items in a table view, how to select a row and display the detail view, and in the next tutorial we will look at how to search the list of items in a table view. I hope you found this tutorial helpful and if you have any questions, please send me an email. Don't forget to leave a comment.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/TableViewPart2.zip"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;UITableView - Loading a detail view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned Table View&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-8208857347384507847?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/3ZE8aTjpjXk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/8208857347384507847/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=8208857347384507847&amp;isPopup=true" title="24 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8208857347384507847" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8208857347384507847" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/3ZE8aTjpjXk/uitableview-loading-detail-view.html" title="UITableView - Loading a detail view" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">24</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-7774696094243816549</id><published>2009-01-13T21:24:00.028-05:00</published><updated>2009-05-09T13:40:03.335-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">UITableView - Creating a Simple Table View</title><content type="html">&lt;span class="previewpost"&gt;If you want to display a list of items in your app, then UITableView object is your answer. The object makes it really easy to display a list of items. In this tutorial, you will learn how to set up a simple table view. Click on "Read more" to get started.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;UITableView - Creating a simple table view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned Table View&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;In most cases, the requirement is to select an item from the list displayed and then load the details of the selected item in a detail view. &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/index.html" target="_blank"&gt;UITableView&lt;/a&gt; is only responsible for the list of items it displays, the navigation that happens between the list of items and the detail view is handled by the &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationController_Class/index.html" target="_blank"&gt;UINavigationController&lt;/a&gt;. So the table view always works with the navigation controller and viceversa. This is how the final app looks like&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgW_3OZ2cGI/AAAAAAAAAHg/lfkXNL7DuNQ/s1600-h/FinalApp.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 166px; height: 320px;" src="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgW_3OZ2cGI/AAAAAAAAAHg/lfkXNL7DuNQ/s320/FinalApp.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5333880289170452578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Creating the project&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new XCode project by clicking on File -&gt; New Project -&gt; (Under iPhone OS) select "Navigation-Based Application", give it a name and save the project. I have named my project "TableView". The project template "Navigation-Based Application" will give you a navigation controller and a table view tied together, so you do not have to set it up manually.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Data Source&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Since we want to display not one or two but a list of items in the table view, we need some kind of a data source to hold our data and something which we can pass it on to the table view so it can use it. This data source can come from anywhere XML Files, Databases, or an array. To learn how to use SQL Lite databases read my SQL Lite tutorial series here. To keep this tutorial simple, I will choose a &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/index.html" target="_blank"&gt;NSMutableArray&lt;/a&gt; as the data source for the table view. You can fill this array from XML files or &lt;a href="http://www.sqlite.org/index.html" target="_blank"&gt;SQLLite&lt;/a&gt; database. The array will be populated with string objects and not custom objects to keep the tutorial less confusing. Read my SQL Lite &lt;a href="http://www.iphonesdkarticles.com/search/label/SQLite" target="_blank"&gt;tutorial&lt;/a&gt; series to understand how to use custom objects with the table view.&lt;br /&gt;&lt;br /&gt;The first thing to do is to build the data source, populate it with the items we need to display in the table view. Let's build our data source in &lt;a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidLoad" target="_blank"&gt;viewDidLoad&lt;/a&gt; method of the RootViewController which is called when the view is loaded. This is how the header file and viewDidLoad method in the implementation file looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;NSMutableArray *listOfItems;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;//viewDidLoad method declared in RootViewController.m&lt;br /&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;//Initialize the array.&lt;br /&gt;listOfItems = [[NSMutableArray alloc] init];&lt;br /&gt;&lt;br /&gt;//Add items&lt;br /&gt;[listOfItems addObject:@"Iceland"];&lt;br /&gt;[listOfItems addObject:@"Greenland"];&lt;br /&gt;[listOfItems addObject:@"Switzerland"];&lt;br /&gt;[listOfItems addObject:@"Norway"];&lt;br /&gt;[listOfItems addObject:@"New Zealand"];&lt;br /&gt;[listOfItems addObject:@"Greece"];&lt;br /&gt;[listOfItems addObject:@"Rome"];&lt;br /&gt;[listOfItems addObject:@"Ireland"];&lt;br /&gt;&lt;br /&gt;//Set the title&lt;br /&gt;self.navigationItem.title = @"Countries";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//dealloc method declared in RootViewController.m&lt;br /&gt;- (void)dealloc {&lt;br /&gt;&lt;br /&gt;[listOfItems release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Array "listOfItems" is declared in RootViewController.h file and is of type NSMutableArray, it is also released in the dealloc method as shown above.&lt;br /&gt;&lt;br /&gt;In viewDidLoad method, we allocate memory and initialize the array and add 8 objects to it. The view of the navigation bar is set to "Countries". Now somehow we need to tell the table view to display the items in the array.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Customize the number of rows in the table view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The first thing we have to do is, tell the table view how many rows it should expect and this is done in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:" target="_blank"&gt;tableView:numberOfRowsInSection&lt;/a&gt;. This method returns an integer which is the number of rows that the table view will display. Since our array consists of 8 objects, we will pass the count message to the array. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {&lt;br /&gt;return [listOfItems count];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Display data in a table cell.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Now that the table view knows how many rows to display, we need to display the actual text which goes in a table view cell. The table view is made of table rows and rows contains table cell. This is done in &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:cellForRowAtIndexPath:" target="_blank"&gt;tableView:cellForRowAtIndexPath&lt;/a&gt; which is called n number of times, where n is the value returned in tableView:numberOfRowsInSection. The method provides indexPath which is of type &lt;a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/NSIndexPath_UIKitAdditions/Reference/Reference.html" target="_blank"&gt;NSIndexPath&lt;/a&gt; and using this we can find out the current row number the table view is going to display. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//RootViewController.m&lt;br /&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Set up the cell...&lt;br /&gt;NSString *cellValue = [listOfItems objectAtIndex:indexPath.row];&lt;br /&gt;cell.text = cellValue;&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the code above, we first initialize the cell if required. Then get the string from the array, by passing objectAtIndex method to the receiver, with the current row number. The "cellValue" is then set to the text of the cell and the cell is returned. Run your application to see the eight rows in the UITableView.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;UITableView really makes it easy to display list of items, by configuring few simple methods. I hope this tutorial helped you in getting started. I know this tutorial is really simple but this way I really get to concentrate on one problem at a time. In my next tutorial,I will show you how to load a detail view and pass data to it.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/TableViewPart1.zip"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;UITableView - Creating a simple table view&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html"&gt;UITableView - Sectioned Table View&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Searching table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-indexed-table-view.html"&gt;UITableView - Indexed table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/uitableview-adding-subviews-to-cells.html"&gt;UITableView - Adding subviews to a cell's content view&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-7774696094243816549?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/gieo-cL3vHU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/7774696094243816549/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=7774696094243816549&amp;isPopup=true" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7774696094243816549" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7774696094243816549" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/gieo-cL3vHU/uitableview-creating-simple-table-view.html" title="UITableView - Creating a Simple Table View" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_ixq8Dp4ESMo/SgW_3OZ2cGI/AAAAAAAAAHg/lfkXNL7DuNQ/s72-c/FinalApp.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-2182030752153334965</id><published>2008-12-19T22:58:00.006-05:00</published><updated>2009-03-15T13:27:13.250-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><category scheme="http://www.blogger.com/atom/ns#" term="Parsing XML" /><title type="text">Parsing XML Files</title><content type="html">&lt;span class="previewpost"&gt;Reading XML files is one of the common tasks we perform in our application, In this tutorial let's see how we can use &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html"&gt;NSXMLParser&lt;/a&gt; to parse XML in our iPhone app.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;NSXMLParser is a forward only reader or an event driven parser. What it means is, an event is raised whenever the parser comes across a start of an element, value, CDATA and so on. The delegate of NSXMLParser can then implement these events to capture XML data. Some of the events are raised multiple times like the start of an element, value of an element and so on. Since NSXMLParser is known as an event driven parser, we can only read data at the present node and cannot go back. The iPhone only supports &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html"&gt;NSXMLParser&lt;/a&gt; and not &lt;a target="_blank" href="http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSXMLDocument_Class/Reference/Reference.html"&gt;NSXMLDocument&lt;/a&gt;, which loads the whole XML tree in memory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Books Application&lt;/span&gt;&lt;br /&gt;To understand how to use an instance of NSXMLParser, let's create a simple navigation based application where we will list the title of the book in the table view and upon selecting a title, display the detail information in a detail view. Click &lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/xml/Books.xml?attredirects=0"&gt;here&lt;/a&gt; to see the sample XML file, used in this application.&lt;br /&gt;&lt;br /&gt;Create a new application in XCode by selecting Navigation-Based Application, I have named my app XML. Since the NSXMLParser is a forward only parser or an event driven parser, we need to store the data locally, which can be used later. To store this data, we will create a class which replicates the elements and attributes in the XML file. An instance of this class represents one single Book element in the XML file. I have named this class "Book" and its source code is listed below&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Book.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface Book : NSObject {&lt;br /&gt;&lt;br /&gt;NSInteger bookID;&lt;br /&gt;NSString *title; //Same name as the Entity Name.&lt;br /&gt;NSString *author; //Same name as the Entity Name.&lt;br /&gt;NSString *summary; //Same name as the Entity Name.&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, readwrite) NSInteger bookID;&lt;br /&gt;@property (nonatomic, retain) NSString *title;&lt;br /&gt;@property (nonatomic, retain) NSString *author;&lt;br /&gt;@property (nonatomic, retain) NSString *summary;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;//Book.m&lt;br /&gt;#import "Book.h"&lt;br /&gt;&lt;br /&gt;@implementation Book&lt;br /&gt;&lt;br /&gt;@synthesize title, author, summary, bookID;&lt;br /&gt;&lt;br /&gt;- (void) dealloc {&lt;br /&gt;&lt;br /&gt;[summary release];&lt;br /&gt;[author release];&lt;br /&gt;[title release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Notice that the name of the property is the same as the element name in the XML file. Since the XML file has n number of Book elements, we need an array to hold all the books we read, so we declare an array in the application delegate and this is how the source code changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLAppDelegate.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface XMLAppDelegate : NSObject &amp;lt;UIApplicationDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt;UIWindow *window;&lt;br /&gt;UINavigationController *navigationController;&lt;br /&gt;&lt;br /&gt;NSMutableArray *books;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UIWindow *window;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSMutableArray *books;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;The Delegate&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;To keep the source code clean, we will also declare a delegate, which will be used by the instance of &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html"&gt;NSXMLParser&lt;/a&gt; and this how its source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLParser.h&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class XMLAppDelegate, Book;&lt;br /&gt;&lt;br /&gt;@interface XMLParser : NSObject {&lt;br /&gt;&lt;br /&gt;NSMutableString *currentElementValue;&lt;br /&gt;&lt;br /&gt;XMLAppDelegate *appDelegate;&lt;br /&gt;Book *aBook;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (XMLParser *) initXMLParser;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's look at how the variables will be used. currentElementValue holds the current element value, appDelegate so we can access the array which holds the list of books and finally a reference to the Book class itself. Notice that we do not keep track of the current element name being processed, because the event will tell us that. Finally, we have a constructor called initXMLParser and let's see what it does&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLParser.m&lt;br /&gt;- (XMLParser *) initXMLParser {&lt;br /&gt;&lt;br /&gt;[super init];&lt;br /&gt;&lt;br /&gt;appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;&lt;br /&gt;return self;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Very simple, gets a reference to the application delegate and returns itself.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Parsing the XML File&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Now that we have everything set up, let's look at the code to read the XML file&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLAppDelegate.m&lt;br /&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NSURL *url = [[NSURL alloc] initWithString:@"http://sites.google.com/site/iphonesdktutorials/xml/Books.xml"];&lt;br /&gt;NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];&lt;br /&gt;&lt;br /&gt;//Initialize the delegate.&lt;br /&gt;XMLParser *parser = [[XMLParser alloc] initXMLParser];&lt;br /&gt;&lt;br /&gt;//Set delegate&lt;br /&gt;[xmlParser setDelegate:parser];&lt;br /&gt;&lt;br /&gt;//Start parsing the XML file.&lt;br /&gt;BOOL success = [xmlParser parse];&lt;br /&gt;&lt;br /&gt;if(success)&lt;br /&gt;NSLog(@"No Errors");&lt;br /&gt;else&lt;br /&gt;NSLog(@"Error Error Error!!!");&lt;br /&gt;&lt;br /&gt;// Configure and show the window&lt;br /&gt;[window addSubview:[navigationController view]];&lt;br /&gt;[window makeKeyAndVisible];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The code is very simple, we create an instance of &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html"&gt;NSURL&lt;/a&gt;, create an instance of NSXMLParser, initialize the delegate, assign the delegate and start parsing by passing the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html#//apple_ref/occ/instm/NSXMLParser/parse"&gt;parse&lt;/a&gt; message. It returns YES, if the parsing is successful, NO if there is an error or if the operation is aborted.&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Parsing the start of an element&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The delegate of the parser does not have to implement all the methods that it raises, so we can pick and choose which events we care about. If we do not want to handle the event when the parser starts reading the document, we can choose to ignore it by not implementing it. We will only implement three methods which is called when the parser encounters the start of an element, end of an element or value of an element.&lt;br /&gt;&lt;br /&gt;Let's look at &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/parser:didStartElement:namespaceURI:qualifiedName:attributes:"&gt;parser:didStartElement:namespaceURI:qualifiedName:attributes&lt;/a&gt; method which is called when the parser encounters the start of an element.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLParser.m&lt;br /&gt;- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName&lt;br /&gt;namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName&lt;br /&gt;attributes:(NSDictionary *)attributeDict {&lt;br /&gt;&lt;br /&gt;if([elementName isEqualToString:@"Books"]) {&lt;br /&gt;//Initialize the array.&lt;br /&gt;appDelegate.books = [[NSMutableArray alloc] init];&lt;br /&gt;}&lt;br /&gt;else if([elementName isEqualToString:@"Book"]) {&lt;br /&gt;&lt;br /&gt;//Initialize the book.&lt;br /&gt;aBook = [[Book alloc] init];&lt;br /&gt;&lt;br /&gt;//Extract the attribute here.&lt;br /&gt;aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];&lt;br /&gt;&lt;br /&gt;NSLog(@"Reading id value :%i", aBook.bookID);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NSLog(@"Processing Element: %@", elementName);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;From the above code we first initialize the array when it encounters the "Books" element, which can also be done in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/parserDidStartDocument:"&gt;parserDidStartDocument&lt;/a&gt; method. If the element is "Book" then we initialize the local book object and read the attribute of the present XML book element from the attribute dictionary object.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Parsing an element's value&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Now that we have a local book object representing the current book element in the XML tree, the next thing to do is to populate the local object with the XML data. The parser now moves to the title element and the same method is called again, but this time we do not do anything. Parser then moves to the element value and it sends &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/parser:foundCharacters:"&gt;parser:foundCharacters&lt;/a&gt; event to the delegate, let's see how the code look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLParser.m&lt;br /&gt;- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {&lt;br /&gt;&lt;br /&gt;if(!currentElementValue)&lt;br /&gt;currentElementValue = [[NSMutableString alloc] initWithString:string];&lt;br /&gt;else&lt;br /&gt;[currentElementValue appendString:string];&lt;br /&gt;&lt;br /&gt;NSLog(@"Processing Value: %@", currentElementValue);&lt;br /&gt;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The code is very easy to read, if the mutable string is nil then we initialize it with the string parameter. If the currentElementValue is not nil then we simply append the data to the existing string value.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Parsing the end of an element&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The parser now moves to the end of the element and hence &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/parser:didEndElement:namespaceURI:qualifiedName:"&gt;parser:didEndElement:namespaceURI:qualifiedName&lt;/a&gt; is sent to the delegate. This is where we set the currentElementValue to the correct property of the local book object and set the currentElementValue to nil. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLParser.m&lt;br /&gt;- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName&lt;br /&gt;namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {&lt;br /&gt;&lt;br /&gt;if([elementName isEqualToString:@"Books"])&lt;br /&gt;return;&lt;br /&gt;&lt;br /&gt;//There is nothing to do if we encounter the Books element here.&lt;br /&gt;//If we encounter the Book element howevere, we want to add the book object to the array&lt;br /&gt;// and release the object.&lt;br /&gt;if([elementName isEqualToString:@"Book"]) {&lt;br /&gt;[appDelegate.books addObject:aBook];&lt;br /&gt;&lt;br /&gt;[aBook release];&lt;br /&gt;aBook = nil;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;[aBook setValue:currentElementValue forKey:elementName];&lt;br /&gt;&lt;br /&gt;[currentElementValue release];&lt;br /&gt;currentElementValue = nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;If the element it encounters is "Books" then there is nothing to do as we are almost done reading the file. If the element name is "Book" then we add the book object to the array and set the local book object to nil and release its memory, so it can be used again. If the end element is not "Books" or "Book" then it must be one of the sub element of "book" and we set the currentElementValue to the current book property using &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html#//apple_ref/occ/instm/NSObject/setValue:forKey:"&gt;setValue:forKey&lt;/a&gt;. We can do this, because the properties declared in the book is the same as the XML element names.&lt;br /&gt;&lt;br /&gt;The cycle starts again by initializing the book object and reading the attribute, reading the children elements and setting its value to the local object and finally adding the object to the array. The parser calls the three functions again and again as long as it does not encounters eof.&lt;br /&gt;&lt;br /&gt;Complete listing of XMLParser.m file&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//XMLParser.m&lt;br /&gt;#import "XMLParser.h"&lt;br /&gt;#import "XMLAppDelegate.h"&lt;br /&gt;#import "Book.h"&lt;br /&gt;&lt;br /&gt;@implementation XMLParser&lt;br /&gt;&lt;br /&gt;- (XMLParser *) initXMLParser {&lt;br /&gt;&lt;br /&gt;[super init];&lt;br /&gt;&lt;br /&gt;appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;&lt;br /&gt;return self;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName&lt;br /&gt;namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName&lt;br /&gt;attributes:(NSDictionary *)attributeDict {&lt;br /&gt;&lt;br /&gt;if([elementName isEqualToString:@"Books"]) {&lt;br /&gt;//Initialize the array.&lt;br /&gt;appDelegate.books = [[NSMutableArray alloc] init];&lt;br /&gt;}&lt;br /&gt;else if([elementName isEqualToString:@"Book"]) {&lt;br /&gt;&lt;br /&gt;//Initialize the book.&lt;br /&gt;aBook = [[Book alloc] init];&lt;br /&gt;&lt;br /&gt;//Extract the attribute here.&lt;br /&gt;aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];&lt;br /&gt;&lt;br /&gt;NSLog(@"Reading id value :%i", aBook.bookID);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NSLog(@"Processing Element: %@", elementName);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {&lt;br /&gt;&lt;br /&gt;if(!currentElementValue)&lt;br /&gt;currentElementValue = [[NSMutableString alloc] initWithString:string];&lt;br /&gt;else&lt;br /&gt;[currentElementValue appendString:string];&lt;br /&gt;&lt;br /&gt;NSLog(@"Processing Value: %@", currentElementValue);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName&lt;br /&gt;namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {&lt;br /&gt;&lt;br /&gt;if([elementName isEqualToString:@"Books"])&lt;br /&gt;return;&lt;br /&gt;&lt;br /&gt;//There is nothing to do if we encounter the Books element here.&lt;br /&gt;//If we encounter the Book element howevere, we want to add the book object to the array&lt;br /&gt;// and release the object.&lt;br /&gt;if([elementName isEqualToString:@"Book"]) {&lt;br /&gt;[appDelegate.books addObject:aBook];&lt;br /&gt;&lt;br /&gt;[aBook release];&lt;br /&gt;aBook = nil;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;[aBook setValue:currentElementValue forKey:elementName];&lt;br /&gt;&lt;br /&gt;[currentElementValue release];&lt;br /&gt;currentElementValue = nil;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) dealloc {&lt;br /&gt;&lt;br /&gt;[aBook release];&lt;br /&gt;[currentElementValue release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;This is how the data looks like in the table view and the detail view controller.&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh3.ggpht.com/_ixq8Dp4ESMo/SYuylQNqNCI/AAAAAAAAAFk/pPW6pbIlPGo/s576/Screen1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://lh3.ggpht.com/_ixq8Dp4ESMo/SYuylQNqNCI/AAAAAAAAAFk/pPW6pbIlPGo/s576/Screen1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh4.ggpht.com/_ixq8Dp4ESMo/SYuylKcgACI/AAAAAAAAAFg/tixNweh2WEI/s576/Screen2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://lh4.ggpht.com/_ixq8Dp4ESMo/SYuylKcgACI/AAAAAAAAAFg/tixNweh2WEI/s576/Screen2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span class="fullpost"&gt;The data is then shown in a &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/index.html"&gt;UITableView&lt;/a&gt; with a detail view, the complete code is not shown here but you can download the source code and to get a better understanding UITableView, you can follow my suggested readings below.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;Reading XML files is very easy and it can be done with only three methods as seen above. I hope this tutorial has got you started in reading XML files. &lt;/span&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/XML.zip"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://www.iphonesdkarticles.com/2009/01/uitableview-creating-simple-table-view.html"&gt;UITableView - Creating a simple table view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target="_blank" href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Loading a detail view&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target="_blank" href="http://www.iphonesdkarticles.com/2009/01/uitableview-searching-table-view.html"&gt;UITableView - Adding a UISearchBar to the UITableView&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-2182030752153334965?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/DO1wpfkagrQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/2182030752153334965/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=2182030752153334965&amp;isPopup=true" title="56 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2182030752153334965" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2182030752153334965" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/DO1wpfkagrQ/parsing-xml-files.html" title="Parsing XML Files" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_ixq8Dp4ESMo/SYuylQNqNCI/AAAAAAAAAFk/pPW6pbIlPGo/s72-c/Screen1.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">56</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/11/parsing-xml-files.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-2892534324518240969</id><published>2008-11-16T12:48:00.029-05:00</published><updated>2009-02-19T21:48:25.250-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="Localization" /><title type="text">Localizing iPhone Apps - Internationalization</title><content type="html">&lt;span class="previewpost"&gt;By localizing an iPhone app, we display cultural information in the user's specified locale, but what about the text, like the application name and displaying visible information in user's preferred language. In this tutorial, I will show you how we can use resource files to display visible text in user's language.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html"&gt;Localizing iPhone Apps - Part 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizating-iphone-apps-custom.html"&gt;Localizing iPhone Apps - Custom Formatter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Localizing iPhone Apps - Internationalization&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Localization and Internationalization are complimentary activities, with one we can display cultural information like units, dates in the user's preferred locale and the other, let's us display text in the user's preferred language.&lt;br /&gt;&lt;br /&gt;The first step is to find out what languages your application is going to support and gather all the text (in different languages), images, videos, sounds and put them in a resource file or in a language directory. To translate text into different languages you can a tool that Google provides &lt;a target="_blank" href="http://translate.google.com/translate_t"&gt;here&lt;/a&gt;. Even if you do not plan to support different languages in your app, it is a good idea to get it set up front.&lt;br /&gt;&lt;br /&gt;The user can change the language by going to Settings -&gt; General -&gt; International -&gt; Language. When the language is changed, the iPhone also changes the name of the application, only if the application supports it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Preparing for Internationalization&lt;/span&gt;&lt;br /&gt;In our sample app, we are going to support two languages English and Italian. Create a new project in Xcode, does not matter what template you select. After you have created your project, open the project location in Finder and create two directories called en.lproj and it.lproj. These two directories become the language project for your application. All the English language resources will stored in the folder en.lproj and the Italian language resources will be stored in it.lproj folder. The resource files that contain the localizable string are called "strings" file and their default name is "Localizable.strings". So, we will create two new strings file in Xcode, select Resources and click on File -&gt; New File -&gt; Other (under Mac OS X) -&gt; Strings file and click on Next, name your file "Localizable.strings" and save it in en.lproj directory. Repeat the same process by saving it in it.lproj directory. This is how the files look like in Xcode, since Xcode is smart enough to figure out that the file is localized for two different languages.&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/locale3/LocalizableStrings.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 184px; height: 106px;" src="http://sites.google.com/site/iphonesdktutorials/images/locale3/LocalizableStrings.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Localizing strings file&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Strings are localized in the format "key" = "value";. The key and the value is in double quotes followed by a semi-colon. You can also add comments above every key-value pair, so the resource file is properly documented. Let's add a key-value resource in English and Italian as follows in its own Localizable.strings file&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Localizable.String file for the English version.&lt;br /&gt;"WelcomeKey" = "Welcome!!!";&lt;br /&gt;//Localizable.strings file for the Italian version.&lt;br /&gt;"WelcomeKey" = "Benvenuto!!!";&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's look at some code on how to get these values from the resource file and display it.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];&lt;br /&gt;NSArray *languages = [defaults objectForKey:@"AppleLanguages"];&lt;br /&gt;NSString *currentLanguage = [languages objectAtIndex:0];&lt;br /&gt;&lt;br /&gt;NSLog(@"Current Locale: %@", [[NSLocale currentLocale] localeIdentifier]);&lt;br /&gt;NSLog(@"Current language: %@", currentLanguage);&lt;br /&gt;NSLog(@"Welcome Text: %@", NSLocalizedString(@"WelcomeKey", @""));&lt;br /&gt;&lt;br /&gt;// Override point for customization after application launch&lt;br /&gt;[window makeKeyAndVisible];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We get the list of languages by using the key &lt;a href="http://developer.apple.com/iphone/library/documentation/MacOSX/Conceptual/BPInternational/Articles/ChoosingLocalizations.html#//apple_ref/doc/uid/20002397-SW4" target="_blank"&gt;AppleLanguages&lt;/a&gt; and then get the first language which is the user's preferred language. We then display some basic information like the locale, language and then display the localized string using &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/macro/NSLocalizedString" target="_blank"&gt;NSLocalizedString&lt;/a&gt; function, which takes two parameters a key and comment which you can leave it blank. The comment parameter does serve a purpose when we want to generate the strings file automatically. Nowhere in the function we specify, from which language directory we want to display the localized string, it is what we can call language sensitive. If it cannot find the preferred language directory then it picks up second language from the list and so on.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating the resource file using genstrings&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Using the genstrings tool, we can create the strings file automatically. Be sure to use NSLocalizedString function every where in your code to display the localized text for a given key. When the tool is used on the source files, it will extract all the keys, comments and create a strings file for you, where the comment is set to be the value for the key. All you then have to do is change the value for the keys according to the the language. You can run the command line tool like this to generate "Localizable.strings" file under en.lproj directory.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;genstrings -o en.lproj *.m&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Before you run the command, make sure the target directory exists.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Localizing iPhone display name&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When the user changes its preferred language, the iPhone will also change the display name for all the apps, if it supports that language. Let's see how we can display the app name in Italian, in English our sample app is called "StringsFile". Create  new strings file and save it in it.lproj directory, with the name "InfoPlist.strings". Add a new entry with the key "CFBundleDisplayName" without quotes and set the value to "Stringhe di file" (I know not a proper translation, but you get the idea). This is how the file should look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;CFBundleDisplayName = "Stringhe di file";&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Now change your preferred language to Italian and the name of your application will be changed. Once you change the language back to English it will say "StringsFile", we do not need to create a new InfoPlist.strings file for English.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Since your iPhone app can be downloaded by anyone in any Country, it becomes extremely important that the app looks and behaves according to the user's locale and language. I hope this tutorial has helped you in localizing your apps.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/StringsFile.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html"&gt;Localizing iPhone Apps - Part 1&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html"&gt;Localizing iPhone Apps - Part 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizating-iphone-apps-custom.html"&gt;Localizing iPhone Apps - Custom Formatter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Localizing iPhone Apps - Internationalization&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-2892534324518240969?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/0TSxqAsZHJo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/2892534324518240969/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=2892534324518240969&amp;isPopup=true" title="24 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2892534324518240969" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2892534324518240969" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/0TSxqAsZHJo/localizing-iphone-apps.html" title="Localizing iPhone Apps - Internationalization" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">24</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-3499042248215018615</id><published>2008-11-11T20:50:00.017-05:00</published><updated>2009-02-19T21:48:19.734-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Localization" /><title type="text">Localizating iPhone Apps - Custom Formatter</title><content type="html">&lt;span class="previewpost"&gt;From time to time you may need to display some information which is locale specific and we may not be able to do it using &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html#//apple_ref/occ/cl/NSNumberFormatter" target="_blank"&gt;NSNumberFormatter&lt;/a&gt; and &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html#//apple_ref/occ/cl/NSDateFormatter" target="_blank"&gt;NSDateFormatter&lt;/a&gt;. Any example might be displaying telephone numbers in a certain format. In such a case, we can create a custom formatter, which is what this tutorial does.&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html"&gt;Localizing iPhone Apps - Part 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Localizing iPhone Apps - Custom Formatter&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps.html"&gt;Localizing iPhone Apps - Internationalization&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The goal of this article is to create a custom formatter, used to display locale specific data. In this tutorial, I will create a new class to format phone numbers based on the user's current locale. If the locale is set to "en_US" then the phone number looks like 1(111)111-1111.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;NSFormatter&lt;/span&gt;&lt;br /&gt;To create a custom formatter, start by creating a new class which inherits from &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html" target="_blank"&gt;NSFormatter&lt;/a&gt;. In Xcode click File -&gt; New File -&gt; NSObject subclass, I have named my file "PhoneNumberFormatter". The new class you create will inherit from NSObject, simple delete that and inherit from &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html" target="_blank"&gt;NSFormatter&lt;/a&gt;. This is how the header file looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@interface PhoneNumberFormatter : NSFormatter {&lt;br /&gt;&lt;br /&gt;NSLocale *locale;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, copy) NSLocale *locale;&lt;br /&gt;&lt;br /&gt;- (NSString *) stringFromPhoneNumber:(NSNumber *)aNumber;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We have a locale property, to keep track of the current user's locale and a method which takes a &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html" target="_blank"&gt;NSNumber&lt;/a&gt; and returns its string representation.&lt;br /&gt;&lt;br /&gt;Since the class inherits from &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html"&gt;NSFormatter&lt;/a&gt;, it needs to override some methods. The three methods that we have to override are &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFormatter/stringForObjectValue:" target="_blank"&gt;stringForObjectValue:(id)anObject&lt;/a&gt;, &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFormatter/getObjectValue:forString:errorDescription:" target="_blank"&gt;getObjectValue:(id)anObject forString:(NSString *)string errorDescription:(NSString *)error&lt;/a&gt; and &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFormatter/attributedStringForObjectValue:withDefaultAttributes:" target="_blank"&gt;attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes&lt;/a&gt;. This has been my understanding so far, if I' am wrong please send me an email. All these methods are really useful in Mac OS X development where we can assign a cell to an &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html"&gt;NSFormatter&lt;/a&gt; object (I have tried to do this in IB for iPhone and it does not work). stringForObjectValue returns NSString object that textually represents the cell's value and the other two methods are also useful in Mac OS X development and not really helpful in iPhone development. As a result, I will not be talking a lot about these methods.&lt;br /&gt;&lt;br /&gt;Lets see how the initWithLocale and stringFromPhoneNumber methods looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) initWithLocale {&lt;br /&gt;[super init];&lt;br /&gt;&lt;br /&gt;locale = [NSLocale currentLocale];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (NSString *) stringFromPhoneNumber:(NSNumber *)aNumber {&lt;br /&gt;&lt;br /&gt;NSString *localeString = [locale localeIdentifier];&lt;br /&gt;NSString *tempStr = [[NSString alloc] initWithString:@""];&lt;br /&gt;NSRange range;&lt;br /&gt;range.length = 3;&lt;br /&gt;range.location = 3;&lt;br /&gt;//Returns the phone number 2032225200 as 1(203)222-5200&lt;br /&gt;if([localeString compare:@"en_US"] == NSOrderedSame) {&lt;br /&gt;NSString *areaCode = [[aNumber stringValue] substringToIndex:3];&lt;br /&gt;NSString *phone1 = [[aNumber stringValue] substringWithRange:range];&lt;br /&gt;NSString *phone2 = [[aNumber stringValue] substringFromIndex:6];&lt;br /&gt;&lt;br /&gt;tempStr = [NSString stringWithFormat:@"1(%@)%@-%@", areaCode, phone1, phone2];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return tempStr;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the initWithLocale method, we get the current user's locale and copy it to the internal variable. In stringFromPhoneNumber we write our logic to display the text representation of the &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html" target="_blank"&gt;NSNumber&lt;/a&gt; value, based on the locale. This is a very simple example and I' am sure there is a better way to parse and display the information.&lt;br /&gt;&lt;br /&gt;Let's also take a look at stringForObjectValue method&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (NSString *) stringForObjectValue:(id)anObject {&lt;br /&gt;&lt;br /&gt;if(![anObject isKindOfClass:[NSNumber class]])&lt;br /&gt;return nil;&lt;br /&gt;else&lt;br /&gt;return [self stringFromPhoneNumber:anObject];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We first check if the object is kind of NSNumber and if it is we simple pass the control to stringFromPhoneNumber message.&lt;br /&gt;&lt;br /&gt;This is how we will use the code in the application&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;NSNumber *phoneNumber = [NSNumber numberWithInt:1231231212];&lt;br /&gt;PhoneNumberFormatter *pnf = [[PhoneNumberFormatter alloc] initWithLocale];&lt;br /&gt;&lt;br /&gt;NSLog(@"Phone Number: %@ for locale: %@", [pnf stringFromPhoneNumber:phoneNumber], [[pnf locale] localeIdentifier]);&lt;br /&gt;&lt;br /&gt;[pnf release];&lt;br /&gt;&lt;br /&gt;// Override point for customization after application launch&lt;br /&gt;[window makeKeyAndVisible];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The phone number and the locale will be displayed on the debugger window.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;Creating a custom formatter, comes in handy when we have to display data like phone numbers and format it according to the user's current locale. By doing this, we also keep our code clean.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/Locale2.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html"&gt;Localizing iPhone Apps - Part 1&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html"&gt;Localizing iPhone Apps - Part 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Localizing iPhone Apps - Custom Formatter&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps.html"&gt;Localizing iPhone Apps - Internationalization&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-3499042248215018615?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/MxyPkdhtJ8k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/3499042248215018615/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=3499042248215018615&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/3499042248215018615" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/3499042248215018615" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/MxyPkdhtJ8k/localizating-iphone-apps-custom.html" title="Localizating iPhone Apps - Custom Formatter" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/11/localizating-iphone-apps-custom.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-3785599934491556344</id><published>2008-11-09T16:43:00.030-05:00</published><updated>2009-05-09T13:27:41.928-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Localization" /><title type="text">Localizing iPhone Apps - Part 1</title><content type="html">&lt;span class="previewpost"&gt;It is very important to localize your iPhone applications, since the app can be used in more then 70 countries. Users want to see information, which is formatted according to their native country or region. &lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;Localizing iPhone Apps - Part 1&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizating-iphone-apps-custom.html"&gt;Localizing iPhone Apps - Custom Formatter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps.html"&gt;Localizing iPhone Apps - Internationalization&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;A Locale is not a language, it is a representation of data like the currency, units, decimal separator or date and time format. A Locale's identifier is represented as languagecode_regioncode_variant. The naming convention is defined by &lt;a href="http://www.icu-project.org/userguide/locale.html" target="_blank"&gt;ICU&lt;/a&gt; (International Components for Unicode). The variant is not required and the locale identifier looks like "en_US" for english in USA and "en_GB" for english in Great Britain". A user can set his/her locale in the iPhone by going to Settings -&gt; General -&gt; International -&gt; Region Format. In this tutorial, we will look at how to display data (like currency, date and time...) in the user's set region or country.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Formatters&lt;/span&gt;&lt;br /&gt;We generally work with the user's current locale object, instead of working with a specific locale. The locale object is used with some other objects, usually formatters. With Cocca, we have &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html#//apple_ref/doc/uid/20000202" target="_blank"&gt;NSNumberFormatter&lt;/a&gt; and &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html#//apple_ref/doc/uid/20000447" target="_blank"&gt;NSDateFormatter&lt;/a&gt;. The classes is locale sensitive, which means when you create an instance it uses the user's current locale, which makes it very easy to work with. NSLocale is a class, which we use to get the user's locale or to create new ones.&lt;br /&gt;&lt;br /&gt;To get the current locale, the code would look something like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;NSLocale *currentUsersLocale = [NSLocale currentLocale];&lt;br /&gt;NSLog(@"Current Locale: %@", [currentUsersLocale localeIdentifier]);&lt;br /&gt;&lt;br /&gt;//Output&lt;br /&gt;Current Locale: en_US&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We get the current locale by passing currentLocale message to the class and we get the locale identifier(string representation) by passing &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html#//apple_ref/occ/instm/NSLocale/localeIdentifier" target="_blank"&gt;localeIdentifier&lt;/a&gt; message. The output will be en_US if the region is set to United States.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Working with NSNumberFormatter&lt;/span&gt;&lt;br /&gt;The code is very easy and it does not take a long time to learn eveything about formatters, we just create new one's and set some properties and use it with the NSNumber class. Below is some code with some sample numbers and different formatters, where the output is displayed on the debugger console.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Get the current user locale.&lt;br /&gt;NSLocale *currentLocale = [NSLocale currentLocale];&lt;br /&gt;NSLog(@"Current Locale: %@", [currentLocale localeIdentifier]);&lt;br /&gt;&lt;br /&gt;NSLog(@"Test numbers: 4.0, 0.4, 4.6, -64");&lt;br /&gt;&lt;br /&gt;NSNumber *number40 = [NSNumber numberWithFloat:4.0];&lt;br /&gt;NSNumber *number04 = [NSNumber numberWithFloat:0.4];&lt;br /&gt;NSNumber *number46 = [NSNumber numberWithFloat:4.6];&lt;br /&gt;NSNumber *number64 = [NSNumber numberWithInt:-64];&lt;br /&gt;&lt;br /&gt;//Working with number 4.0 and representing as No Style&lt;br /&gt;NSNumberFormatter *noStyleFormatter = [[NSNumberFormatter alloc] init];&lt;br /&gt;[noStyleFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];&lt;br /&gt;[noStyleFormatter setNumberStyle:NSNumberFormatterNoStyle];&lt;br /&gt;&lt;br /&gt;//Decimal Style&lt;br /&gt;NSNumberFormatter *decimalStyle = [[NSNumberFormatter alloc] init];&lt;br /&gt;[decimalStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];&lt;br /&gt;[decimalStyle setNumberStyle:NSNumberFormatterDecimalStyle];&lt;br /&gt;[decimalStyle setRoundingMode:NSNumberFormatterRoundFloor];&lt;br /&gt;[decimalStyle setRoundingIncrement:[NSNumber numberWithInt:1]];&lt;br /&gt;&lt;br /&gt;//Currency Style&lt;br /&gt;NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];&lt;br /&gt;[currencyStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];&lt;br /&gt;[currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];&lt;br /&gt;&lt;br /&gt;//Percent Style&lt;br /&gt;NSNumberFormatter *percentStyle = [[NSNumberFormatter alloc] init];&lt;br /&gt;[percentStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];&lt;br /&gt;[percentStyle setNumberStyle:NSNumberFormatterPercentStyle];&lt;br /&gt;&lt;br /&gt;//Scientific Style&lt;br /&gt;NSNumberFormatter *scientificStyle = [[NSNumberFormatter alloc] init];&lt;br /&gt;[scientificStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];&lt;br /&gt;[scientificStyle setNumberStyle:NSNumberFormatterScientificStyle];&lt;br /&gt;&lt;br /&gt;//Spell Out Style&lt;br /&gt;NSNumberFormatter *spellOutStyle = [[NSNumberFormatter alloc] init];&lt;br /&gt;[spellOutStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];&lt;br /&gt;[spellOutStyle setNumberStyle:NSNumberFormatterSpellOutStyle];&lt;br /&gt;&lt;br /&gt;NSLog(@"Locale of noStyle formatter: %@", [[noStyleFormatter locale] localeIdentifier]);&lt;br /&gt;NSLog(@"Locale of decimal style formatter: %@", [[decimalStyle locale] localeIdentifier]);&lt;br /&gt;NSLog(@"Locale of currency style formatter: %@", [[currencyStyle locale] localeIdentifier]);&lt;br /&gt;NSLog(@"Locale of percent style formatter: %@", [[percentStyle locale] localeIdentifier]);&lt;br /&gt;NSLog(@"Locale of scientific style formatter: %@", [[scientificStyle locale] localeIdentifier]);&lt;br /&gt;NSLog(@"Locale of spell-out style formatter: %@", [[spellOutStyle locale] localeIdentifier]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;&lt;br /&gt;//Display Results&lt;br /&gt;NSLog(@"Different formatting results for NSNumber 4.0 with Locale: %@", [currentLocale localeIdentifier]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;NSLog(@"Formatting 4.0 with No Style: %@", [noStyleFormatter stringFromNumber:number40]);&lt;br /&gt;NSLog(@"Formatting 4.0 with Decimal Style: %@", [decimalStyle stringFromNumber:number40]);&lt;br /&gt;NSLog(@"Formatting 4.0 with Currency Style: %@", [currencyStyle stringFromNumber:number40]);&lt;br /&gt;NSLog(@"Formatting 4.0 with Percent Style: %@", [percentStyle stringFromNumber:number40]);&lt;br /&gt;NSLog(@"Formatting 4.0 with Scientific Style: %@", [scientificStyle stringFromNumber:number40]);&lt;br /&gt;NSLog(@"Formatting 4.0 with Spell Out Style: %@", [spellOutStyle stringFromNumber:number40]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;&lt;br /&gt;NSLog(@"Different formatting results for NSNumber 0.4 with Locale: %@", [currentLocale localeIdentifier]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;NSLog(@"Formatting with No Style: %@", [noStyleFormatter stringFromNumber:number04]);&lt;br /&gt;NSLog(@"Formatting with Decimal Style: %@", [decimalStyle stringFromNumber:number04]);&lt;br /&gt;NSLog(@"Formatting with Currency Style: %@", [currencyStyle stringFromNumber:number04]);&lt;br /&gt;NSLog(@"Formatting with Percent Style: %@", [percentStyle stringFromNumber:number04]);&lt;br /&gt;NSLog(@"Formatting with Scientific Style: %@", [scientificStyle stringFromNumber:number04]);&lt;br /&gt;NSLog(@"Formatting with Spell Out Style: %@", [spellOutStyle stringFromNumber:number04]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;&lt;br /&gt;NSLog(@"Different formatting results for NSNumber 4.6 with Locale: %@", [currentLocale localeIdentifier]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;NSLog(@"Formatting with No Style: %@", [noStyleFormatter stringFromNumber:number46]);&lt;br /&gt;NSLog(@"Formatting with Decimal Style: %@", [decimalStyle stringFromNumber:number46]);&lt;br /&gt;NSLog(@"Formatting with Currency Style: %@", [currencyStyle stringFromNumber:number46]);&lt;br /&gt;NSLog(@"Formatting with Percent Style: %@", [percentStyle stringFromNumber:number46]);&lt;br /&gt;NSLog(@"Formatting with Scientific Style: %@", [scientificStyle stringFromNumber:number46]);&lt;br /&gt;NSLog(@"Formatting with Spell Out Style: %@", [spellOutStyle stringFromNumber:number46]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;&lt;br /&gt;NSLog(@"Different formatting results for NSNumber -64 with Locale: %@", [currentLocale localeIdentifier]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;br /&gt;NSLog(@"Formatting with No Style: %@", [noStyleFormatter stringFromNumber:number64]);&lt;br /&gt;NSLog(@"Formatting with Decimal Style: %@", [decimalStyle stringFromNumber:number64]);&lt;br /&gt;NSLog(@"Formatting with Currency Style: %@", [currencyStyle stringFromNumber:number64]);&lt;br /&gt;NSLog(@"Formatting with Percent Style: %@", [percentStyle stringFromNumber:number64]);&lt;br /&gt;NSLog(@"Formatting with Scientific Style: %@", [scientificStyle stringFromNumber:number64]);&lt;br /&gt;NSLog(@"Formatting with Spell Out Style: %@", [spellOutStyle stringFromNumber:number64]);&lt;br /&gt;NSLog(@"---------------------------------------");&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;All the code does is, create a bunch of formatters based on different styles and we see how the data looks like. The formatters behavior is set to &lt;/span&gt;&lt;span class="fullpost"&gt;NSNumberFormatterBehavior10_4, telling the formatter to behave since Mac OS X 10.4. We display the number by passing &lt;/span&gt;&lt;span class="fullpost"&gt;&lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNumberFormatter/stringFromNumber:" target="_blank"&gt;stringFromNumber&lt;/a&gt; message to the formatter. With &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html"&gt;NSNumberFormatter&lt;/a&gt;, you can set the currency symbol, set positive/negative symbols and it lets you do change many default settings. Click &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html"&gt;here&lt;/a&gt; to get a list of all the methods and properties which you can work with.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Working with NSDateFormatter&lt;/span&gt;&lt;br /&gt;Just like &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html"&gt;NSNumberFormatter&lt;/a&gt;, &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html"&gt;NSDateFormatter&lt;/a&gt; is also locale sensitive. This is some sample code, showing how to use the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html"&gt;NSDateFormatter&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Date Formatters.&lt;br /&gt;[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];&lt;br /&gt;NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];&lt;br /&gt;[dateFormatter setDateStyle:NSDateFormatterLongStyle];&lt;br /&gt;[dateFormatter setTimeStyle:NSDateFormatterNoStyle];&lt;br /&gt;NSDate *date = [NSDate date];&lt;br /&gt;&lt;br /&gt;NSString *formattedDateString = [dateFormatter stringFromDate:date];&lt;br /&gt;NSLog(@"Formatted date string for locale %@: %@", [[dateFormatter locale] localeIdentifier], formattedDateString);&lt;br /&gt;&lt;br /&gt;//Custom Date Formatter.&lt;br /&gt;NSDateFormatter *customDateFormatter = [[NSDateFormatter alloc] init];&lt;br /&gt;&lt;br /&gt;//When setting the date format, do not set the date and time format style.&lt;br /&gt;//Only one of the two can be set if not, the latter setting will take precedence.&lt;br /&gt;[customDateFormatter setDateFormat:@"'The time is' hh:mm 'on' EEEE MMMM d"];&lt;br /&gt;&lt;br /&gt;NSLog(@"%@", [customDateFormatter stringFromDate:date]);&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;NSDateFormatter lets you do many things, set months symbol, set the time zone, set the AM/PM symbols, click &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html"&gt;here&lt;/a&gt; to find out all the methods and properties you can use with NSDateFormatter.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Always use a formatter when display currency, units and datetime so it is always displayed in the user's current locale. I know, this article was pretty simple and the code propably does not a whole lot, but I hope it helped you a little bit.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/Locale.zip"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;Localizing iPhone Apps - Part 1&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizating-iphone-apps-custom.html"&gt;Localizing iPhone Apps - Custom Formatter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps.html"&gt;Localizing iPhone Apps - Internationalization&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-3785599934491556344?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/PcV6rEl07NU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/3785599934491556344/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=3785599934491556344&amp;isPopup=true" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/3785599934491556344" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/3785599934491556344" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/PcV6rEl07NU/localizing-iphone-apps-part-1.html" title="Localizing iPhone Apps - Part 1" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-8238125886043274719</id><published>2008-11-01T20:32:00.046-04:00</published><updated>2009-02-12T00:36:05.670-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">SQLite Tutorial - Updating data</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial, I will show you how to edit data and update its contents  in the &lt;a target="_blank" href="http://www.sqlite.org/index.html"&gt;SQLite&lt;/a&gt; database. We will look at how to edit one field at a time.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;In the detail view, the user will be able to edit the fields by clicking the edit button and selecting a row at a time to load the edit view. When the data is updated in the edit view, we will mark the object as dirty. Data will only be saved in the database when the application is being terminated or when it receives a memory warning.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Editing Data&lt;/span&gt;&lt;br /&gt;First thing we have to do is, place the edit button on the left bar. We add the button in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidLoad"&gt;viewDidLoad&lt;/a&gt; method and this is how the source code looks like for DetailViewController.m&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt; &lt;br /&gt;self.navigationItem.rightBarButtonItem = self.editButtonItem;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;When the edit button is clicked, we will hide the back button and let the user know that the row can be selected to edit. This is how the code is going to look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)setEditing:(BOOL)editing animated:(BOOL)animated {&lt;br /&gt;[super setEditing:editing animated:animated];&lt;br /&gt;[self.navigationItem setHidesBackButton:editing animated:animated];&lt;br /&gt; &lt;br /&gt;[tableView reloadData];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/setEditing:animated:"&gt;setEditing&lt;/a&gt; is called when the user clicks on the edit button and it is where we hide or show the back button. The table view is also refreshed, so we can set the accessory type. To hide the back button use &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationItem_Class/Reference/UINavigationItem.html#//apple_ref/occ/instm/UINavigationItem/setHidesBackButton:animated:"&gt;setHidesBackButton&lt;/a&gt; message. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (UITableViewCellAccessoryType)tableView:(UITableView *)tv accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;// Show the disclosure indicator if editing.&lt;br /&gt;return (self.editing) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:accessoryTypeForRowWithIndexPath:"&gt;accessoryTypeForRowWithIndexPath&lt;/a&gt; gets called to use a disclosure control for the specified row. Based on the editing variable status, an indicator is set. You may have noticed that, the row can be selected even if the user did not click on the edit view. The following code takes care of that&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (NSIndexPath *)tableView:(UITableView *)tv willSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;// Only allow selection if editing.&lt;br /&gt;return (self.editing) ? indexPath : nil;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:willSelectRowAtIndexPath:"&gt;willSelectRowAtIndexPath&lt;/a&gt; tells the delegate that a specified row is about to be selected and is called before didSelectRowAtIndexPath. Return the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSIndexPath"&gt;indexPath&lt;/a&gt; selected if the user clicks on edit and nil if the done button is clicked.&lt;br /&gt;&lt;br /&gt;Now we handle the event &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:"&gt;didSelectRowAtIndexPath&lt;/a&gt;, which is called when a row is selected. The user will select a row to load the edit view where a value can be changed.&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creating the edit view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new view in Interface Builder and name it "EditView". Place a text field on the view and set the property capitalize to Words and uncheck "Clear when editing begings" field. leave all the other properties as default. Then add UINavigationBar from the library to the EditView nib file and place two bar button items on the right and left bar button items. Set the style of the left button item to Cancel and the right one to Save.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating the edit view controller&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;In Xcode create a new UIViewController and name it "EditViewController". This is how the header file looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;@interface EditViewController : UIViewController {&lt;br /&gt; &lt;br /&gt; IBOutlet UITextField *txtField;&lt;br /&gt; NSString *keyOfTheFieldToEdit;&lt;br /&gt; NSString *editValue;&lt;br /&gt; id objectToEdit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) id objectToEdit;&lt;br /&gt;@property (nonatomic, retain) NSString *keyOfTheFieldToEdit;&lt;br /&gt;@property (nonatomic, retain) NSString *editValue;&lt;br /&gt;&lt;br /&gt;- (IBAction) save_Clicked:(id)sender;&lt;br /&gt;- (IBAction) cancel_Clicked:(id)sender;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's finish working with the Interface Builder first, by making all the right connections.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Text Field Properties&lt;br /&gt;&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/TextBoxProperties.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 268px; height: 146px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/TextBoxProperties.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;File's Owner Class Identity&lt;br /&gt;&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/FilesOwnerClass.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 292px; height: 116px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/FilesOwnerClass.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Edit View Nib File&lt;br /&gt;&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/NibFile.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 426px; height: 333px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/NibFile.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Navigation Bar with two buttons&lt;br /&gt;&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/NavBar.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 66px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/NavBar.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;File's Owner Connections&lt;br /&gt;&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/FilesOwnerProperties.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 282px; height: 248px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite5/FilesOwnerProperties.jpg" alt="" border="0" /&gt;&lt;/a&gt;Coming back to the EditViewController header file, notice that we do not have a reference to the Coffee class any where, the edit view controller does not know anything about what object it is going to edit and we want to keep it this way. Let's look at the properties defined in the header file and see what they are meant to to. txtField is a reference to the text field placed on the view, keyOfTheFieldToEdit is the key of the field we are going to edit or the property name as string, editValue is going to be the value we are about to edit (this is the value which will be displayed on the text field) and objectToEdit declared as type id which is going to be the Coffee object itself. save_Clicked and cancel_Clicked handle the events when save or cancel are clicked.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Selecting a row to edit&lt;/span&gt;&lt;br /&gt;Let's go back to the Detail view controller and look at what goes on in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:"&gt;didSelectRowAtIndexPath&lt;/a&gt; method. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)tableView:(UITableView *)tblView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt; &lt;br /&gt; //Keep track of the row selected.&lt;br /&gt; selectedIndexPath = indexPath;&lt;br /&gt; &lt;br /&gt; if(evController == nil)&lt;br /&gt;  evController = [[EditViewController alloc] initWithNibName:@"EditView" bundle:nil];&lt;br /&gt; &lt;br /&gt; //Find out which field is being edited.&lt;br /&gt; switch(indexPath.section)&lt;br /&gt; {&lt;br /&gt;  case 0:&lt;br /&gt;   evController.keyOfTheFieldToEdit = @"coffeeName";&lt;br /&gt;   evController.editValue = coffeeObj.coffeeName;&lt;br /&gt;   break;&lt;br /&gt;  case 1:&lt;br /&gt;   evController.keyOfTheFieldToEdit = @"price";&lt;br /&gt;   evController.editValue = [coffeeObj.price stringValue];&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //Object being edited.&lt;br /&gt; evController.objectToEdit = coffeeObj;&lt;br /&gt; &lt;br /&gt; //Push the edit view controller on top of the stack.&lt;br /&gt; [self.navigationController pushViewController:evController animated:YES];&lt;br /&gt; &lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;selectedIndexPath is a new variable declared in the Coffee header file, which is of type &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSIndexPath"&gt;NSIndexPath&lt;/a&gt;. The variable is used to keep track of which row was selected, so we can deselect it when the detail view is shown. evController is declared in the header file and is of type EditViewController. This is how the code looks like in the DetailViewController header file&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;@class Coffee, EditViewController;&lt;br /&gt;&lt;br /&gt;@interface DetailViewController : UIViewController &amp;lt;UITableViewDataSource, UITableViewDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt; IBOutlet UITableView *tableView;&lt;br /&gt; Coffee *coffeeObj;&lt;br /&gt; NSIndexPath *selectedIndexPath;&lt;br /&gt; EditViewController *evController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) Coffee *coffeeObj;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Coming back to didSelectRowAtIndexPath, first thing we do is keep track of the row selected then initialize the controller if it is nil. We then find out which row to edit and assign "keyOfTheFieldToEdit", "editValue" and objectToEdit properties. keyOfTheFieldToEdit takes the name of the property, edit value takes the value to edit and objectToEdit takes the coffee object. Since objectToEdit is declared as id and not Coffee, this view can be used to edit any object. We will see how to edit the coffee object soon. At last, the edit view controller is pushed to the top of the stack.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Display data in edit view&lt;/span&gt;&lt;br /&gt;To make the edit view look pretty, let's give it a background color. In viewDidLoad method, set the view's background color to &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIColor_Class/Reference/Reference.html#//apple_ref/occ/clm/UIColor/groupTableViewBackgroundColor"&gt;groupTableViewBackgroundColor&lt;/a&gt;, and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt; &lt;br /&gt; self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Back to EditViewController, in viewWillAppear method, we are going to set the text of the text field and also the title of the view. The title of the view is going to be the property we are about to edit, which we get it from keyOfTheFieldToEdit variable, this also becomes the placeholder text for the text field. Since, we are only going to edit one field in this view, it makes sense to have the keyboard show up when the view is loaded. This way the user does not have to tap the text field. We do this by passing the message &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/becomeFirstResponder"&gt;becomeFirstResponder&lt;/a&gt; to text field. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewWillAppear:(BOOL)animated {&lt;br /&gt; &lt;br /&gt; [super viewWillAppear:YES];&lt;br /&gt; &lt;br /&gt; self.title = [self.keyOfTheFieldToEdit capitalizedString];&lt;br /&gt; txtField.placeholder = [self.keyOfTheFieldToEdit capitalizedString];&lt;br /&gt; &lt;br /&gt; txtField.text = self.editValue;&lt;br /&gt; &lt;br /&gt; [txtField becomeFirstResponder];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The code is pretty self explanatory, we get the property name as capitalized string by passing the message &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/capitalizedString"&gt;capitalizedString&lt;/a&gt; and show the text field by passing becomeFirstResponder to the text field.&lt;br /&gt;&lt;br /&gt;Now we have to handle save_Clicked and cancel_Clicked methods. This is how the code looks like for the cancel method&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (IBAction) cancel_Clicked:(id)sender {&lt;br /&gt; &lt;br /&gt; [self.navigationController popViewControllerAnimated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We simply pop the present view controller from the stack to show the detail view controller, by passing &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instm/UINavigationController/popViewControllerAnimated:"&gt;popViewControllerAnimated&lt;/a&gt; message.&lt;br /&gt;&lt;br /&gt;This is how the save_Clicked method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (IBAction) save_Clicked:(id)sender {&lt;br /&gt; &lt;br /&gt; //Update the value.&lt;br /&gt; //Invokes the set&amp;lt;key&amp;gt; method defined in the Coffee Class.&lt;br /&gt; [objectToEdit setValue:txtField.text forKey:self.keyOfTheFieldToEdit];&lt;br /&gt; &lt;br /&gt; //Pop back to the detail view.&lt;br /&gt; [self.navigationController popViewControllerAnimated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Two lines, without any comments. This is what I love about iPhone programming, we can update any object by just passing a message to the object and asking it to change some properties. &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html#//apple_ref/occ/instm/NSObject/setValue:forKey:"&gt;setValue&lt;/a&gt; does all the tricks, which will set the property of the receiver specified by a given key to a given value (text borrowed from documentation).&lt;br /&gt;&lt;br /&gt;However, I found out that I was not able to set the value of boolean property isDirty to YES using setValue:forKey and that is why I had to write my own version of setCoffeeName and setPrice. According to the design of this app, we will only save data which has been changed in memory, to the database when the application is terminated or the app receives a memory warning. This way we reduce the round trip from the app to the database, making it a little faster.&lt;br /&gt;&lt;br /&gt;This is how the setCoffeeName and setPrice methods look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) setCoffeeName:(NSString *)newValue {&lt;br /&gt; &lt;br /&gt; self.isDirty = YES;&lt;br /&gt; [coffeeName release];&lt;br /&gt; coffeeName = [newValue copy];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) setPrice:(NSDecimalNumber *)newNumber {&lt;br /&gt; &lt;br /&gt; self.isDirty = YES;&lt;br /&gt; [price release];&lt;br /&gt; price = [newNumber copy];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Since the property is declared with &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/copy"&gt;copy&lt;/a&gt; attribute, we get the copy of the newValue and assign it to the local variable. The isDirty property is also set to YES.&lt;br /&gt;&lt;br /&gt;When the user clicks on save, the detail view is shown but the row which was selected is still highlighted. To deselect the row, pass &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/deselectRowAtIndexPath:animated:"&gt;deselectRowAtIndexPath&lt;/a&gt; message to the table view, the message is passed in viewWillDisappear method and this how the code looks like. You can call this method in viewWillAppear method too&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewWillDisappear:(BOOL)animated {&lt;br /&gt; &lt;br /&gt; [tableView deselectRowAtIndexPath:selectedIndexPath animated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We still have to update the data in the SQLite database and write code for it. Data is only updated when the app is about to be terminated or when a memory warning is received. &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/applicationWillTerminate:"&gt;applicationWillTerminate&lt;/a&gt; method is called when the app is shutting down, which is declared in SQLAppDelegate.m file. This is how the code will change&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)applicationWillTerminate:(UIApplication *)application {&lt;br /&gt; // Save data if appropriate&lt;br /&gt; &lt;br /&gt; //Save all the dirty coffee objects and free memory.&lt;br /&gt; [self.coffeeArray makeObjectsPerformSelector:@selector(saveAllData)];&lt;br /&gt; &lt;br /&gt; [Coffee finalizeStatements];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/Reference/Reference.html#//apple_ref/occ/instm/NSArray/makeObjectsPerformSelector:"&gt;makeObjectsPerformSelector&lt;/a&gt; sends saveAllData message to each object in the array. So we are going to declare a method in the Coffee class header file called "saveAllData" and write the implementation in the implementation file (Coffee.m file)&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Complete code listing not shown&lt;br /&gt;- (void) hydrateDetailViewData;&lt;br /&gt;- (void) saveAllData;&lt;br /&gt;...&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Code in Coffee.m file looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) saveAllData {&lt;br /&gt; &lt;br /&gt; if(isDirty) {&lt;br /&gt;  &lt;br /&gt;  if(updateStmt == nil) {&lt;br /&gt;   const char *sql = "update Coffee Set CoffeeName = ?, Price = ? Where CoffeeID = ?";&lt;br /&gt;   if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;updateStmt, NULL) != SQLITE_OK)&lt;br /&gt;    NSAssert1(0, @"Error while creating update statement. '%s'", sqlite3_errmsg(database));&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  sqlite3_bind_text(updateStmt, 1, [coffeeName UTF8String], -1, SQLITE_TRANSIENT);&lt;br /&gt;  sqlite3_bind_double(updateStmt, 2, [price doubleValue]);&lt;br /&gt;  sqlite3_bind_int(updateStmt, 3, coffeeID);&lt;br /&gt;  &lt;br /&gt;  if(SQLITE_DONE != sqlite3_step(updateStmt))&lt;br /&gt;   NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(database));&lt;br /&gt;  &lt;br /&gt;  sqlite3_reset(updateStmt);&lt;br /&gt;  &lt;br /&gt;  isDirty = NO;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //Reclaim all memory here.&lt;br /&gt; [coffeeName release];&lt;br /&gt; coffeeName = nil;&lt;br /&gt; [price release];&lt;br /&gt; price = nil;&lt;br /&gt; &lt;br /&gt; isDetailViewHydrated = NO;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We only save the data of the objects which has been changed in memory. updatestmt is declared as static and is of type &lt;a target="_blank" href="http://www.sqlite.org/c3ref/stmt.html"&gt;sqlite3_stmt&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Complete code listing now shown.&lt;br /&gt;static sqlite3_stmt *detailStmt = nil;&lt;br /&gt;static sqlite3_stmt *updateStmt = nil;&lt;br /&gt;&lt;br /&gt;@implementation Coffee&lt;br /&gt;...&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We prepare the update statement if it is nil, then assign the variables to the update statement where the index starts from 1 and not 0. The method &lt;a target="_blank" href="http://www.sqlite.org/c3ref/step.html"&gt;sqlite3_step&lt;/a&gt; is called and if it returns &lt;a target="_blank" href="http://www.sqlite.org/c3ref/c_abort.html"&gt;SQLITE_DONE&lt;/a&gt; then we know that the update was a success. Finally we reset the updatestmt so it can be reused later. The update statement like any other statement is finalized in finalizeStatements method which looks like this, which is implemented in Coffee.m file.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;+ (void) finalizeStatements {&lt;br /&gt; &lt;br /&gt; if (database) sqlite3_close(database);&lt;br /&gt; if (deleteStmt) sqlite3_finalize(deleteStmt);&lt;br /&gt; if (addStmt) sqlite3_finalize(addStmt);&lt;br /&gt; if (detailStmt) sqlite3_finalize(detailStmt);&lt;br /&gt; if (updateStmt) sqlite3_finalize(updateStmt);&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;When the application receives a memory warning, "&lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html"&gt;applicationDidReceiveMemoryWarning&lt;/a&gt;" is called which is implemented in SQLAppDelegate.m file and this is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;//Save all the dirty coffee objects and free memory.&lt;br /&gt; [self.coffeeArray makeObjectsPerformSelector:@selector(saveAllData)];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Here the message finalizeStatements is not passed to the Coffee class because the application is not shutting down.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;This tutorial shows how to save data in a edit view by passing the setValue message, shows how to save dirty data to the database when the application is terminated or when it receives a memory warning. This also concludes the SQLite tutorial series.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/SQL5.zip"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Selecting Data&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting Data&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-8238125886043274719?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/XqpfAwtkABc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/8238125886043274719/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=8238125886043274719&amp;isPopup=true" title="18 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8238125886043274719" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8238125886043274719" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/XqpfAwtkABc/sqlite-tutorial-updating-data.html" title="SQLite Tutorial - Updating data" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">18</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-5962591036413787741</id><published>2008-10-30T22:09:00.049-04:00</published><updated>2009-02-12T00:50:13.146-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">SQLite Tutorial - Loading data as required.</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial, I was supposed to show how to update data in a SQLite database, but when I finished writing it, I realized that it is a big one and that is why, I renamed this tutorial to "Loading data as required".&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Loading data as required.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Introduction&lt;/span&gt;&lt;br /&gt;In this tutorial, I will show you how to select a row and load the Coffee class details in a detail view. According to the design of this app, we only load data when we need it. Now we load the price of coffee from the SQLite database, when a row is selected. This is the fourth tutorial in SQLite tutorial series and it borrows its source code from the previous tutorials. This is how the detail view looks like&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/DetailView.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/DetailView.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span class="fullpost"&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Selecting data from database&lt;/span&gt;&lt;br /&gt;Since we need to get the price of a coffee from the database and show it on the detail view, let's declare a method called "hydrateDetailViewData" in Coffee class and this is how the method deceleration looks like in Coffee.h File&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) hydrateDetailViewData;&lt;br /&gt;//Complete code listing not shown.&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;and the method is implemented in Coffee.m, this is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) hydrateDetailViewData {&lt;br /&gt;&lt;br /&gt;//If the detail view is hydrated then do not get it from the database.&lt;br /&gt;if(isDetailViewHydrated) return;&lt;br /&gt;&lt;br /&gt;if(detailStmt == nil) {&lt;br /&gt;const char *sql = "Select price from Coffee Where CoffeeID = ?";&lt;br /&gt;if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;detailStmt, NULL) != SQLITE_OK)&lt;br /&gt; NSAssert1(0, @"Error while creating detail view statement. '%s'", sqlite3_errmsg(database));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sqlite3_bind_int(detailStmt, 1, coffeeID);&lt;br /&gt;&lt;br /&gt;if(SQLITE_DONE != sqlite3_step(detailStmt)) {&lt;br /&gt;&lt;br /&gt;//Get the price in a temporary variable.&lt;br /&gt;NSDecimalNumber *priceDN = [[NSDecimalNumber alloc] initWithDouble:sqlite3_column_double(detailStmt, 0)];&lt;br /&gt;&lt;br /&gt;//Assign the price. The price value will be copied, since the property is declared with "copy" attribute.&lt;br /&gt;self.price = priceDN;&lt;br /&gt;&lt;br /&gt;//Release the temporary variable. Since we created it using alloc, we have own it.&lt;br /&gt;[priceDN release];&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;NSAssert1(0, @"Error while getting the price of coffee. '%s'", sqlite3_errmsg(database));&lt;br /&gt;&lt;br /&gt;//Reset the detail statement.&lt;br /&gt;sqlite3_reset(detailStmt);&lt;br /&gt;&lt;br /&gt;//Set isDetailViewHydrated as YES, so we do not get it again from the database.&lt;br /&gt;isDetailViewHydrated = YES;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;As always, detailStmt is declared as static and is of type &lt;a href="http://www.sqlite.org/c3ref/stmt.html" target="_blank"&gt;sqlite3_stmt&lt;/a&gt;, this is the code&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;static sqlite3_stmt *addStmt = nil;&lt;br /&gt;static sqlite3_stmt *detailStmt = nil;&lt;br /&gt;&lt;br /&gt;@implementation Coffee&lt;br /&gt;//Complete code listing not shown.&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Let's see what happens in hydrateDetailViewData, the first thing we check is if detailStmt is nil or not, if it is then we prepare the statement using &lt;a href="http://www.sqlite.org/c3ref/prepare.html" target="_blank"&gt;sqlite3_prepare_v2&lt;/a&gt; function with the correct SQL query. The query "Select price from Coffee Where CoffeeID = ?" takes one parameter represented by one '?'. Parameters are assigned to the statement using the function &lt;a target="_blank" href="http://www.sqlite.org/c3ref/bind_blob.html"&gt;sqlite3_bind_int&lt;/a&gt;, since the parameter is going to be the type of int. Notice, that the index is represented as 1 and not 0, this is because when assigning parameters the index starts from 1. The statement is executed using &lt;a href="http://www.sqlite.org/c3ref/step.html" target="_blank"&gt;sqlite3_step&lt;/a&gt; method and &lt;a href="http://www.sqlite.org/c3ref/c_abort.html" target="_blank"&gt;SQLITE_DONE&lt;/a&gt; is returned on success. We get the price in a temporary variable priceDN, using the function &lt;a target="_blank" href="http://www.sqlite.org/c3ref/column_blob.html"&gt;sqlite3_column_double&lt;/a&gt;, then our temporary variable is initialized using &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNumber/initWithDouble:"&gt;initWithDouble&lt;/a&gt; method. We assign the temporary variable to the price variable and then release it, which we have to do since the object was created using the alloc method. Remember price property is declared in the Coffee class using the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/copy"&gt;copy&lt;/a&gt; attribute and not &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/retain"&gt;retain&lt;/a&gt;, this way we do not increment the count on priceDN but copy it to the price variable. The statement is reset using &lt;a target="_blank" href="http://www.sqlite.org/c3ref/reset.html"&gt;sqlite3_reset&lt;/a&gt;, so it can be used again without preparing the statement again.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating the detail view&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Now that we have a routine to get the price of a coffee, let's create the detail view and the detail view controller. First let's create the UIViewController, in Xcode (Select the Classes Folder) create a new file which inherits from UIViewController (File -&gt; New File -&gt; Select UIViewController SubClass) and name it "DetailViewController".  Lets add some variables and properties to it, coffeeObj to hold the Coffee object and tableView which will be placed on the Detail View (to be created in IB). This is how the header file looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;@class Coffee;&lt;br /&gt;&lt;br /&gt;@interface DetailViewController : UIViewController &amp;lt;UITableViewDataSource, UITableViewDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt;IBOutlet UITableView *tableView;&lt;br /&gt;Coffee *coffeeObj;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) Coffee *coffeeObj;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the implementation file of the DetailViewController, the property is synthesized and both the variables are released in the dealloc method.&lt;br /&gt;&lt;br /&gt;Let's see what happens in IB. Create a new view in IB and name it "DetailView". Place a UITableView on the view and change the style property to "Grouped". Since I always have a hard time explaining what goes in IB, here are the screen shots of the connections.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Class Identity for File's Owner Object&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/ClassDetails.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 300px; height: 123px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/ClassDetails.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Controller Connections for File's Owner&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/FilesOwner.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 292px; height: 199px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/FilesOwner.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Table View Connections&lt;br /&gt;&lt;/div&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/TableView.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 297px; height: 156px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlite4/TableView.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Selecting a row&lt;/span&gt;&lt;br /&gt;We are doing all this work to display the detail view when a row is selected, lets look at the code on how to do that&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;// Navigation logic -- create and push a new view controller&lt;br /&gt;&lt;br /&gt;if(dvController == nil)&lt;br /&gt;dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:nil];&lt;br /&gt;&lt;br /&gt;Coffee *coffeeObj = [appDelegate.coffeeArray objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Get the detail view data if it does not exists.&lt;br /&gt;//We only load the data we initially want and keep on loading as we need.&lt;br /&gt;[coffeeObj hydrateDetailViewData];&lt;br /&gt;&lt;br /&gt;dvController.coffeeObj = coffeeObj;&lt;br /&gt;&lt;br /&gt;[self.navigationController pushViewController:dvController animated:YES];&lt;br /&gt;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We have a new variable defined here called "dvController" and it is defined in the header file like this and it is also released in the dealloc method.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Complete code listing not shown&lt;br /&gt;DetailViewController *dvController;&lt;br /&gt;...&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Coming back to "&lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:"&gt;didSelectRowAtIndexPath&lt;/a&gt;" method, the first thing we do is check if dvController is nil or not, if it is we initialize it. We then get the coffee object from the array and send "hydrateDetailViewData" message to get the price of the coffee. The coffee object is assigned to the detail view controller so it is available to the detail view. The detail view is shown to the user using &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instm/UINavigationController/pushViewController:animated:"&gt;pushViewController&lt;/a&gt; method.&lt;br /&gt;&lt;br /&gt;Now that a row can be selected, we have to let the user know that it can be done. We can do that by setting the &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/accessoryType"&gt;accessoryType&lt;/a&gt; property of the cell in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:cellForRowAtIndexPath:"&gt;cellForRowAtIndexPath&lt;/a&gt;, this is how the code looks like now&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Get the object from the array.&lt;br /&gt;Coffee *coffeeObj = [appDelegate.coffeeArray objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Set the coffename.&lt;br /&gt;cell.text = coffeeObj.coffeeName;&lt;br /&gt;&lt;br /&gt;//Set the accessory type.&lt;br /&gt;cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;&lt;br /&gt;&lt;br /&gt;// Set up the cell&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;br /&gt;Displaying data in the detail view&lt;/span&gt;&lt;br /&gt;Let's see what we have to do in the detail view. From the detail view image (at the top), we can tell that coffeeName and price shows up in a table view with "Coffee Name" and "Price" as the title of the section name. The first thing we will do is, set the title of the view with the coffee name and we do this in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewWillAppear:"&gt;viewWillAppear&lt;/a&gt; method, this is how the source code looks like, which is pretty self explanatory.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) viewWillAppear:(BOOL)animated {&lt;br /&gt;&lt;br /&gt;[super viewWillAppear:animated];&lt;br /&gt;&lt;br /&gt;self.title = coffeeObj.coffeeName;&lt;br /&gt;&lt;br /&gt;[tableView reloadData];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Since we only have to show two fields on the view, we will return 2 in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/numberOfSectionsInTableView:"&gt;numberOfSectionsInTableView&lt;/a&gt; method and as only one coffee data will be displayed, we return 1 in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/numberOfRowsInSection:"&gt;numberOfRowsInSection&lt;/a&gt; method. This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (NSInteger)numberOfSectionsInTableView:(UITableView *)tblView {&lt;br /&gt;return 2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- (NSInteger)tableView:(UITableView *)tblView numberOfRowsInSection:(NSInteger)section {&lt;br /&gt;return 1;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Next thing we have to do is give names to our section, which is set in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:titleForHeaderInSection:"&gt;titleForHeaderInSection&lt;/a&gt; method. It gets called n number of times, where n is the number returned in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/numberOfSectionsInTableView:"&gt;numberOfSectionsInTableView&lt;/a&gt;. This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (NSString *)tableView:(UITableView *)tblView titleForHeaderInSection:(NSInteger)section {&lt;br /&gt;&lt;br /&gt;NSString *sectionName = nil;&lt;br /&gt;&lt;br /&gt;switch (section) {&lt;br /&gt;case 0:&lt;br /&gt; sectionName = [NSString stringWithFormat:@"Coffee Name"];&lt;br /&gt; break;&lt;br /&gt;case 1:&lt;br /&gt; sectionName = [NSString stringWithFormat:@"Price"];&lt;br /&gt; break;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return sectionName;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Now we set the text of the cell which is returned in &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/cellForRowAtIndexPath:"&gt;cellForRowAtIndexPath&lt;/a&gt;, which gets called n number of times where n is the number returned in numberOfRowsInSection. I would like to mention one thing here, for example if your table view can only show 4 rows and we return 10 in numberOfRowsInSection then, cellForRowAtIndexPath is only called 4 times because that is what the user sees. When the user scrolls to see more data, it is then cellForRowAtIndexPath is called again to display additional data.&lt;br /&gt;&lt;br /&gt;This is how cellForRowAtIndexPath method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;switch(indexPath.section) {&lt;br /&gt;case 0:&lt;br /&gt; cell.text = coffeeObj.coffeeName;&lt;br /&gt; break;&lt;br /&gt;case 1:&lt;br /&gt; cell.text = [NSString stringWithFormat:@"%@", coffeeObj.price];&lt;br /&gt; break;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;NOTE: When this post was published, I had a error in case 1. I had earlier set the price of the coffee by passing stringValue message to the receiver, which works now but gives an error in the next tutorial. &lt;br /&gt;&lt;br /&gt;In this method, after getting UITableViewCell, we find out the index of the section from &lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSIndexPath"&gt;indexPath&lt;/a&gt; object. If it is 0 then we set the coffeeName property, if it is 1 then we set the price property. Price of the coffee is set as string to the text property of the cell.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;By following this design pattern, where we only load the data we need to show to the user and loading additional data as required, we adhere to the Apple's recommended way of accessing data.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/SQL4.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/01/uitableview-loading-detail-view.html"&gt;UITableView - Passing data to a detail view.&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Selecting Data&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Loading data as required.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-5962591036413787741?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/AYobvSlZ9TY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/5962591036413787741/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=5962591036413787741&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/5962591036413787741" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/5962591036413787741" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/AYobvSlZ9TY/sqlite-tutorial-loading-data-as.html" title="SQLite Tutorial - Loading data as required." /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-7947399592187695544</id><published>2008-10-27T21:56:00.033-04:00</published><updated>2009-02-12T00:48:06.053-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">SQLite Tutorial - Adding data</title><content type="html">&lt;span class="previewpost"&gt;Inserting data into SQLite database is a breeze with iPhone applications. In the third part of &lt;a target="_blank" href="http://www.sqlite.org/index.html"&gt;SQLite&lt;/a&gt; tutorials, I will show how to insert data into the database.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;br /&gt;Introduction&lt;/span&gt;&lt;br /&gt;Adding data into the database is very simple using the &lt;a href="http://www.sqlite.org/index.html" target="_blank"&gt;SQLite&lt;/a&gt; library, although there are some tweaks we have to perform if we want the application to behave in a certain way. This tutorial picks up its source code from the last tutorial in this series. This is how the "AddView" looks like&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/FinalApp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/FinalApp.jpg" alt="" border="0" /&gt;&lt;/a&gt;The work flow is as following, a user will click on the "Add" button on the left hand bar button item and the "AddView" will be presented to him. The user will enter the coffee name and price and click on "Save" on the navigation item on the right hand side to save it. Internally, it will call "save_Clicked" method which will create a "Coffee" object and set all the right properties. We then call "add_Coffee" method on "SQLAppDelegate" which will call "add_Coffee" method on the "Coffee" class and then it will add the object to the array. We then dismiss the add view controller and reload data on the table view in "viewWillAppear" method implemented in "RootViewController.m".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Creating the addCoffee Method&lt;/span&gt;&lt;br /&gt;First thing we do is create the addCoffee method in the Coffee class which is responsible for inserting data in the database.&lt;br /&gt;&lt;br /&gt;This is how the header file looks like (Complete code not shown)&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) addCoffee;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;and the method is implemented in Coffee.m file&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) addCoffee {&lt;br /&gt;&lt;br /&gt;if(addStmt == nil) {&lt;br /&gt;const char *sql = "insert into Coffee(CoffeeName, Price) Values(?, ?)";&lt;br /&gt;if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;addStmt, NULL) != SQLITE_OK)&lt;br /&gt;NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sqlite3_bind_text(addStmt, 1, [coffeeName UTF8String], -1, SQLITE_TRANSIENT);&lt;br /&gt;sqlite3_bind_double(addStmt, 2, [price doubleValue]);&lt;br /&gt;&lt;br /&gt;if(SQLITE_DONE != sqlite3_step(addStmt))&lt;br /&gt;NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));&lt;br /&gt;else&lt;br /&gt;//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid&lt;br /&gt;coffeeID = sqlite3_last_insert_rowid(database);&lt;br /&gt;&lt;br /&gt;//Reset the add statement.&lt;br /&gt;sqlite3_reset(addStmt);&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The "add_Stmt" is declared as static sqlite3_stmt variable. It is finalized in finalizeStatements and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Complete code listing not shown&lt;br /&gt;#import "Coffee.h"&lt;br /&gt;&lt;br /&gt;static sqlite3 *database = nil;&lt;br /&gt;static sqlite3_stmt *deleteStmt = nil;&lt;br /&gt;static sqlite3_stmt *addStmt = nil;&lt;br /&gt;&lt;br /&gt;@implementation Coffee&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;+ (void) finalizeStatements {&lt;br /&gt;&lt;br /&gt;if(database) sqlite3_close(database);&lt;br /&gt;if(deleteStmt) sqlite3_finalize(deleteStmt);&lt;br /&gt;if(addStmt) sqlite3_finalize(addStmt);&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Coming back to addCoffee method, "add_Stmt" is built using the appropriate insert SQL code. To bind the coffee name the following method &lt;a target="_blank" href="http://www.sqlite.org/c3ref/bind_blob.html"&gt;sqlite3_bind_text&lt;/a&gt; is used and &lt;a href="http://www.sqlite.org/c3ref/bind_blob.html" target="_blank"&gt;sqlite3_bind_double&lt;/a&gt; is used to bind the price variable to the insert statement. Since the method only accepts a value of datatype double, we send &lt;a href="https://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDecimalNumber_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDecimalNumber/doubleValue" target="_blank"&gt;doubleValue&lt;/a&gt; message to the receiver. Execute the statement using sqlite_step method and if it returns &lt;a href="http://www.sqlite.org/c3ref/c_abort.html" target="_blank"&gt;SQLITE_DONE&lt;/a&gt; then the row was successfully added to the database. We still do not have the primary key for the row which was inserted, which we can get by calling &lt;a href="http://www.sqlite.org/c3ref/last_insert_rowid.html" target="_blank"&gt;sqlite3_last_insert_rowid&lt;/a&gt; method and passing the database object. The "rowid" is only returned on column of type INTEGER PRIMARY KEY.&lt;br /&gt;&lt;br /&gt;After adding the data in the database, we have to add the coffee object to the coffeeArray declared in SQLAppDelegate class. To do this we will declare a method called "add_Coffee" which will take a parameter of type Coffee and this method is called from "save_Clicked" method, which is called when the user clicks on the save button.&lt;br /&gt;&lt;br /&gt;This is how the header file changes (Full code not shown)&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//FileName: SQLAppDelegate.h&lt;br /&gt;- (void) addCoffee:(Coffee *)coffeeObj;&lt;br /&gt;...&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;addCoffee is implemented in SQLAppDelegate.m file and this is the code listing&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) addCoffee:(Coffee *)coffeeObj {&lt;br /&gt;&lt;br /&gt;//Add it to the database.&lt;br /&gt;[coffeeObj addCoffee];&lt;br /&gt;&lt;br /&gt;//Add it to the coffee array.&lt;br /&gt;[coffeeArray addObject:coffeeObj];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The first line calls the "addCoffee" method on the coffee object which we just created. The second line adds the object in the array.&lt;br /&gt;&lt;br /&gt;Now we have to work with the Add View and its associated view controller.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Adding new UIView&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new view using the Interface Builder, I have named the view "AddView". Add two labels and two text boxes as shown in the figure below. For the text fields, Capitalize is set to "Words", Return Key is set to "Done" and set the Placeholder as "Coffee Name" and "Price" for the two respective text fields. You would set the properties in "Text Field Attributes" (Tools -&gt; Inspector) using IB. Open "Connections Inspector" and create a connection from the delegate property to "File's Owner" object, do the same for both the text boxes. I find it hard to explain what goes in IB, so here is a screen shot of how it should look like. The "Text Field Connections" applies to both the text boxes.&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/AddView.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 332px; height: 239px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/AddView.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/Delegate.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 292px; height: 93px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/Delegate.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Creating a UIViewController&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new view controller (using Xcode), the name of my file is "AddViewController". Create two variables of type UITextField with "IBOutlet" attribute so the variables show up in IB and create two methods called "save_Clicked" and "cancel_Clicked". This is how the header file should look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class Coffee;&lt;br /&gt;&lt;br /&gt;@interface AddViewController : UIViewController {&lt;br /&gt;&lt;br /&gt;IBOutlet UITextField *txtCoffeeName;&lt;br /&gt;IBOutlet UITextField *txtPrice;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Now that we have defined "AddViewController" set the File's Owner class as "AddViewController" in "Controller Identity", below is a screen shot of that.&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/ClassIdentity.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 276px; height: 91px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/ClassIdentity.jpg" alt="" border="0" /&gt;&lt;/a&gt;Also link the text fields declared in the view controller to the objects on the "AddView", below is a screen shot of that&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/Connections.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 296px; height: 226px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart3/Connections.jpg" alt="" border="0" /&gt;&lt;/a&gt;We are done with using Interface builder, feels good now that we can concentrate on code.&lt;br /&gt;&lt;br /&gt;We now have to add two buttons "Cancel" and "Save" on the "UINavigationItem" of the "AddView". Let us do this in "viewDidLoad" method and this how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;self.title = @"Add Coffee";&lt;br /&gt;&lt;br /&gt;self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]&lt;br /&gt;   initWithBarButtonSystemItem:UIBarButtonSystemItemCancel&lt;br /&gt;    target:self action:@selector(cancel_Clicked:)] autorelease];&lt;br /&gt;&lt;br /&gt;self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]&lt;br /&gt;    initWithBarButtonSystemItem:UIBarButtonSystemItemSave&lt;br /&gt;    target:self action:@selector(save_Clicked:)] autorelease];&lt;br /&gt;&lt;br /&gt;self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Everything is self explanatory, we set the title, add two buttons and set the background of the view by passing &lt;a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIColor_Class/Reference/Reference.html#//apple_ref/occ/clm/UIColor/groupTableViewBackgroundColor" target="_blank"&gt;groupTableViewBackgroundColor&lt;/a&gt; message to &lt;a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIColor_Class/Reference/Reference.html" target="_blank"&gt;UIColor&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Since the view has only two text fields, it will be easier if the keypad is presented to the user when the view is loaded. Lets do this in "viewWillAppear" method and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) viewWillAppear:(BOOL)animated {&lt;br /&gt;[super viewWillAppear:animated];&lt;br /&gt;&lt;br /&gt;//Set the textboxes to empty string.&lt;br /&gt;txtCoffeeName.text = @"";&lt;br /&gt;txtPrice.text = @"";&lt;br /&gt;&lt;br /&gt;//Make the coffe name textfield to be the first responder.&lt;br /&gt;[txtCoffeeName becomeFirstResponder];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Here we always set the text property of the text fields to empty string and we make the keypad show up for the coffeeName text field by passing &lt;a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/becomeFirstResponder" target="_blank"&gt;becomeFirstResponder&lt;/a&gt; message.&lt;br /&gt;&lt;br /&gt;Since the user can click "Done" the keyboard should be hidden and the method which gets called is &lt;a target="_blank" href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html#//apple_ref/occ/intfm/UITextFieldDelegate/textFieldShouldReturn:"&gt;textFieldShouldReturn&lt;/a&gt; and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {&lt;br /&gt;&lt;br /&gt;[theTextField resignFirstResponder];&lt;br /&gt;return YES;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Please note that, I send "resignFirstResponder" message to the text field without finding out which textbox should be hidden. I do this because, the actual save happens in "save_clicked" method.&lt;br /&gt;&lt;br /&gt;Before we look at "save_Clicked" method, this is how "cancel_Clicked" method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) cancel_Clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;//Dismiss the controller.&lt;br /&gt;[self.navigationController dismissModalViewControllerAnimated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;and this is how the "save_Clicked" method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) save_Clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;SQLAppDelegate *appDelegate = (SQLAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;&lt;br /&gt;//Create a Coffee Object.&lt;br /&gt;Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:0];&lt;br /&gt;coffeeObj.coffeeName = txtCoffeeName.text;&lt;br /&gt;NSDecimalNumber *temp = [[NSDecimalNumber alloc] initWithString:txtPrice.text];&lt;br /&gt;coffeeObj.price = temp;&lt;br /&gt;[temp release];&lt;br /&gt;coffeeObj.isDirty = NO;&lt;br /&gt;coffeeObj.isDetailViewHydrated = YES;&lt;br /&gt;&lt;br /&gt;//Add the object&lt;br /&gt;[appDelegate addCoffee:coffeeObj];&lt;br /&gt;&lt;br /&gt;//Dismiss the controller.&lt;br /&gt;[self.navigationController dismissModalViewControllerAnimated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We create a new coffee class and set all the properties, isDetailViewHydrated is set as YES because all the data is in memory and isDirty is set as NO because the row will be inserted in the database after setting all the properties. The view is dismissed by passing "dismissModalViewControllerAnimated" message to the receiver.&lt;br /&gt;&lt;br /&gt;We still have to add the "Add" button to the "RootViewController" and add the code to show the "AddView". This is how the header file changes for "RootViewController"&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class Coffee, AddViewController;&lt;br /&gt;&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;SQLAppDelegate *appDelegate;&lt;br /&gt;AddViewController *avController;&lt;br /&gt;UINavigationController *addNavigationController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Do not forget to import "AddViewController.h" in "RootViewController.m" file. The "Add" button is added in the "viewDidLoad" method and this is how the code changes&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;self.navigationItem.rightBarButtonItem = self.editButtonItem;&lt;br /&gt;&lt;br /&gt;self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]&lt;br /&gt;  initWithBarButtonSystemItem:UIBarButtonSystemItemAdd&lt;br /&gt;  target:self action:@selector(add_Clicked:)];&lt;br /&gt;&lt;br /&gt;appDelegate = (SQLAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;&lt;br /&gt;self.title = @"Coffee List";&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;When "Add" is clicked "add_Clicked" method is called and this is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) add_Clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;if(avController == nil)&lt;br /&gt;avController = [[AddViewController alloc] initWithNibName:@"AddView" bundle:nil];&lt;br /&gt;&lt;br /&gt;if(addNavigationController == nil)&lt;br /&gt;addNavigationController = [[UINavigationController alloc] initWithRootViewController:avController];&lt;br /&gt;&lt;br /&gt;[self.navigationController presentModalViewController:addNavigationController animated:YES];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The reason we present the "AddView" using "addNavigationController" because when we want a custom UINavigationItem to show up on the AddView and that is why we initialize "addNavigationController" with "avController" and present it using "presentModalViewController".&lt;br /&gt;&lt;br /&gt;Run your application to insert data in the database.&lt;br /&gt;&lt;br /&gt;There is however a problem with the design here, a User can click on Edit and nothing restricts him/her from clicking the add button. The code below fixes the issue&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)setEditing:(BOOL)editing animated:(BOOL)animated {&lt;br /&gt; &lt;br /&gt; [super setEditing:editing animated:animated];&lt;br /&gt;   [self.tableView setEditing:editing animated:YES];&lt;br /&gt; &lt;br /&gt; //Do not let the user add if the app is in edit mode.&lt;br /&gt; if(editing)&lt;br /&gt;  self.navigationItem.leftBarButtonItem.enabled = NO;&lt;br /&gt; else&lt;br /&gt;  self.navigationItem.leftBarButtonItem.enabled = YES;&lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method &lt;a href="https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/setEditing:animated:" target="_blank"&gt;setEditing&lt;/a&gt; is called when the edit button is clicked. We send the same message to the parent class and the tableview, also disable or enable the leftBarButtonItem if the tableview is in edit mode.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;As we can see inserting data in SQLite databases is very easy to do.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/SQL3.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html" target="_blank"&gt;SQLite Tutorial - Deleting data&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the SQLite database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-7947399592187695544?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/wr4OE2fDy1E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/7947399592187695544/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=7947399592187695544&amp;isPopup=true" title="27 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7947399592187695544" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7947399592187695544" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/wr4OE2fDy1E/sqlite-tutorial-adding-data.html" title="SQLite Tutorial - Adding data" /><author><name>jai</name><uri>http://www.blogger.com/profile/09514342500729931901</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17629479702229410159" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">27</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-290780023444739988</id><published>2008-10-26T19:12:00.034-04:00</published><updated>2009-02-12T00:47:28.567-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">SQLite Tutorial - Deleting Data</title><content type="html">&lt;span class="previewpost"&gt;In the second part of the &lt;a target="_blank" href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt; tutorial, I will show how to delete data from UITableView and from the database. This picks up from the first part of the SQLite tutorial, where I show how to select some data from the database and display it to the user.&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Sometimes we do need to delete data and this is what we will learn to do in this tutorial. If you haven't read the part 1 of this tutorial you can read it &lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Deleting a row from UITableView&lt;/span&gt;&lt;br /&gt;To delete data, we first need to delete the row from the table and then delete it from the UITableView, it is not necessary to do it in that order. Data can be deleted by using the edit button or by swiping your finger across the UITableViewCell.&lt;br /&gt;&lt;br /&gt;When a row is deleted from the UITableView "commitEditingStyle" method is called which can be found in RootViewController.m.&lt;br /&gt;&lt;br /&gt;This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle&lt;br /&gt;forRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;if(editingStyle == UITableViewCellEditingStyleDelete) {&lt;br /&gt;&lt;br /&gt;            //Get the object to delete from the array.&lt;br /&gt;Coffee *coffeeObj = [appDelegate.coffeeArray objectAtIndex:indexPath.row];&lt;br /&gt;[appDelegate removeCoffee:coffeeObj];&lt;br /&gt;&lt;br /&gt;//Delete the object from the table.&lt;br /&gt;[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];&lt;br /&gt;}&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We first check if the editingStyle is "&lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableViewCellEditingStyleDelete"&gt;UITableViewCellEditingStyleDelete&lt;/a&gt;" or not, if it is then we first delete the row from the database and then from the UITableView using "&lt;a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/deleteRowsAtIndexPaths:withRowAnimation:"&gt;deleteRowsAtIndexPaths&lt;/a&gt;" method.&lt;br /&gt;&lt;br /&gt;Since we have not yet implemented "removeCoffee" method, let's do that now.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Deleting rows from the database&lt;/span&gt;&lt;br /&gt;Declare "removeCoffee" in "SQLAppDelegate.h" file which takes a "Coffee" object as a parameter and returns void, the code looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Complete code listing not shown&lt;br /&gt;- (void) removeCoffee:(Coffee *)coffeeObj;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method does two things, sends a message to the Coffee Object to delete itself from the database and removes the object from the coffeeArray. The method is implemented in SQLAppDelegate.m file and looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) removeCoffee:(Coffee *)coffeeObj {&lt;br /&gt;&lt;br /&gt;//Delete it from the database.&lt;br /&gt;[coffeeObj deleteCoffee];&lt;br /&gt;&lt;br /&gt;//Remove it from the array.&lt;br /&gt;[coffeeArray removeObject:coffeeObj];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The first line, it sends a "deleteCoffee" message to the coffee object, let's see how the code for that looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;//Method is declared in the header file.&lt;br /&gt;//Full code listing not shown&lt;br /&gt;- (void) deleteCoffee;&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;"deleteCoffee" is implemented in SQLAppDelegate.m file.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) deleteCoffee {&lt;br /&gt;&lt;br /&gt;if(deleteStmt == nil) {&lt;br /&gt;const char *sql = "delete from Coffee where coffeeID = ?";&lt;br /&gt;if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;deleteStmt, NULL) != SQLITE_OK)&lt;br /&gt; NSAssert1(0, @"Error while creating delete statement. '%s'", sqlite3_errmsg(database));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//When binding parameters, index starts from 1 and not zero.&lt;br /&gt;sqlite3_bind_int(deleteStmt, 1, coffeeID);&lt;br /&gt;&lt;br /&gt;if (SQLITE_DONE != sqlite3_step(deleteStmt))&lt;br /&gt;NSAssert1(0, @"Error while deleting. '%s'", sqlite3_errmsg(database));&lt;br /&gt;&lt;br /&gt;sqlite3_reset(deleteStmt);&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The "deleteStmt" as a static variable whose type is sqlite3_stmt. Deceleration shown below&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import "Coffee.h"&lt;br /&gt;&lt;br /&gt;static sqlite3 *database = nil;&lt;br /&gt;static sqlite3_stmt *deleteStmt = nil;&lt;br /&gt;&lt;br /&gt;@implementation Coffee&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We first prepare the delete statement with the sql query "delete from Coffee where CoffeeID = ?". The '?' specifies that we have to pass a parameter to the statement, we do this using &lt;a target="_blank" href="http://www.sqlite.org/c3ref/bind_blob.html"&gt;sqlite3_bind_int&lt;/a&gt; method since the parameter we have to pass is an int. Note that the index is specified as 1 and not 0 because when assigining parameters the index starts from 1 and not 0. sqlite_step is called to execute the delete statement and if it returns "SQLITE_DONE" it means that the row is deleted successfully. &lt;a target="_blank" href="http://www.sqlite.org/c3ref/c_abort.html"&gt;Click here&lt;/a&gt; to get a list of complete return codes by SQLite. We then reset the delete statement so it can be reused later, without having the need to build it.&lt;br /&gt;&lt;br /&gt;Run your application and delete a row to test.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;Deleting rows is very easy and straight forward. In my next tutorial, I will show you insert data in the database.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Attachments&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/SQL2.zip" target="_blank"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html" target="_blank"&gt;SQLite Tutorial - Deleting data&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the SQLite database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html"&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-290780023444739988?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/JW1p0bg9E68" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/290780023444739988/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=290780023444739988&amp;isPopup=true" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/290780023444739988" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/290780023444739988" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/JW1p0bg9E68/sqlite-tutorial-deleting-data.html" title="SQLite Tutorial - Deleting Data" /><author><name>jai</name><uri>http://www.blogger.com/profile/09514342500729931901</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17629479702229410159" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-8763282710379412721</id><published>2008-10-25T21:55:00.040-04:00</published><updated>2009-02-12T00:46:51.620-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQLite" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><title type="text">SQLite Tutorial - Selecting Data</title><content type="html">&lt;span class="previewpost"&gt;Like any other applications you may have the need to store data in some kind of a database. With iPhone applications we can use &lt;a href="http://www.sqlite.org/" target="_blank"&gt;SQLite&lt;/a&gt; for FREE. In the first part of this tutorial, I will show you how to do some basic operations using SQLite database.&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Like any other applications you may have the need to store data in some kind of a database. For iPhone applications, we can use &lt;a target="_blank" href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt; for free. SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. Note: iPhone applications cannot work with remote databases.&lt;br /&gt;&lt;br /&gt;In this tutorial, I will discuss how to create a new SQLite database and use it in a iPhone application.&lt;br /&gt;&lt;br /&gt;This is how the application will look like&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart1/FinalApp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 386px; height: 742px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart1/FinalApp.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;SQLite Manager&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;To use SQLite in your application, you do not have to install any new software on your mac. You can either use the command line to create a new SQL database or use &lt;a target="_blank" href="https://addons.mozilla.org/en-US/firefox/addon/5817"&gt;SQLite Manager for Firefox&lt;/a&gt; add-on, which is what I use.&lt;br /&gt;&lt;br /&gt;The screenshots below shows you the database schema used, which is very simple.&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart1/SQLiteManager.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 700px; height: 529px;" src="http://sites.google.com/site/iphonesdktutorials/images/sqlitepart1/SQLiteManager.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;iPhone App&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create a new project by selecting Navigation-based application. The name of the project used for this tutorial is "SQL". We first need to add a library which understands how to communicate with the SQLite database. In Xcode select "Frameworks" folder and click on the Action dropdown and select Add -&gt; Existing Frameworks and browse to /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.1.sdk/usr/lib and select libsqlite3.0.dylib file and it will be added in the "Frameworks" folder.&lt;br /&gt;&lt;br /&gt;Now add the SQLite database file to the "Resources" folder in Xcode.&lt;br /&gt;&lt;br /&gt;Next we need to create a data structure to hold the data from the database. Create a new class and name it "Coffee". This is how the class looks like.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;#import &amp;lt;sqlite3.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface Coffee : NSObject {&lt;br /&gt;&lt;br /&gt;NSInteger coffeeID;&lt;br /&gt;NSString *coffeeName;&lt;br /&gt;NSDecimalNumber *price;&lt;br /&gt;&lt;br /&gt;//Intrnal variables to keep track of the state of the object.&lt;br /&gt;BOOL isDirty;&lt;br /&gt;BOOL isDetailViewHydrated;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, readonly) NSInteger coffeeID;&lt;br /&gt;@property (nonatomic, copy) NSString *coffeeName;&lt;br /&gt;@property (nonatomic, copy) NSDecimalNumber *price;&lt;br /&gt;&lt;br /&gt;@property (nonatomic, readwrite) BOOL isDirty;&lt;br /&gt;@property (nonatomic, readwrite) BOOL isDetailViewHydrated;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Note that in the "Coffee" class the price variable is declared as "&lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSDecimalNumber_Class/Reference/Reference.html" target="_blank"&gt;NSDecimalNumber&lt;/a&gt;" because in the database its corresponding column is of type "REAL". Note: Although SQLite does not enforce data type constraints, it is good practice to enforce data type constraints at the application level. The two boolean variables keep track of the state of the object. The boolean "isDirty" tells us if the object was changed in memory or not and "isDetailViewHydrated" tell us, if the data which shows up on the detail view is fetched from the database or not.&lt;br /&gt;&lt;br /&gt;NOTE: It is good practice to fetch only the data required to show on the screen, which makes the application load faster. So in our case, we will only get the primary key and the name of the coffee from the database as the price is only shown in the detail view.&lt;br /&gt;&lt;br /&gt;Synthesize the properties and release price and coffeeName in the dealloc method. This is how the implementation file of class "Coffee" looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import "Coffee.h"&lt;br /&gt;&lt;br /&gt;@implementation Coffee&lt;br /&gt;&lt;br /&gt;@synthesize coffeeID, coffeeName, price, isDirty, isDetailViewHydrated;&lt;br /&gt;&lt;br /&gt;- (void) dealloc {&lt;br /&gt;&lt;br /&gt;[price release];&lt;br /&gt;[coffeeName release];&lt;br /&gt;[super dealloc];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Copying the database&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The first thing we need to do when the application loads is to check whether the user's phone has the database or not, if not then we copy it to the user's phone. We will create two methods which will help us in copying the database to the user's phone. This is how SQLAppDelegate header file will look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class Coffee;&lt;br /&gt;&lt;br /&gt;@interface SQLAppDelegate : NSObject &amp;lt;UIApplicationDelegate&amp;gt; {&lt;br /&gt;&lt;br /&gt;UIWindow *window;&lt;br /&gt;UINavigationController *navigationController;&lt;br /&gt;&lt;br /&gt;//To hold a list of Coffee objects&lt;br /&gt;NSMutableArray *coffeeArray;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UIWindow *window;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) NSMutableArray *coffeeArray;&lt;br /&gt;&lt;br /&gt;- (void) copyDatabaseIfNeeded;&lt;br /&gt;- (NSString *) getDBPath;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;coffeeArray is the array used to hold all the "Coffee" objects. It is declared in the application delegate file and not anywhere else is because the object lives in memory as long as the application is running and it also gets a notification when the application is being terminated. The method copyDatabaseIfNeeded is used to copy the database on the user's phone when the application is finished launching. Another method used with "copyDatabaseIfNeeded" is "getDBPath" which gets the database location on the user's phone.&lt;br /&gt;&lt;br /&gt;This is how "copyDatabaseIfNeeded" method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void) copyDatabaseIfNeeded {&lt;br /&gt;&lt;br /&gt;//Using NSFileManager we can perform many file system operations.&lt;br /&gt;NSFileManager *fileManager = [NSFileManager defaultManager];&lt;br /&gt;NSError *error;&lt;br /&gt;NSString *dbPath = [self getDBPath];&lt;br /&gt;BOOL success = [fileManager fileExistsAtPath:dbPath];&lt;br /&gt;&lt;br /&gt;if(!success) {&lt;br /&gt;&lt;br /&gt;NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"SQL.sqlite"];&lt;br /&gt;success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&amp;amp;error];&lt;br /&gt;&lt;br /&gt;if (!success)&lt;br /&gt;NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);&lt;br /&gt;}&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;and this is how the getDBPath method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (NSString *) getDBPath {&lt;br /&gt;&lt;br /&gt;//Search for standard documents using NSSearchPathForDirectoriesInDomains&lt;br /&gt;//First Param = Searching the documents directory&lt;br /&gt;//Second Param = Searching the Users directory and not the System&lt;br /&gt;//Expand any tildes and identify home directories.&lt;br /&gt;NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);&lt;br /&gt;NSString *documentsDir = [paths objectAtIndex:0];&lt;br /&gt;return [documentsDir stringByAppendingPathComponent:@"SQL.sqlite"];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In "copyDatabaseIfNeeded" method we get the NSFileManager object with which we can perform some basic file management tasks. The method "getDBPath" gives us the database location on the user's phone. Method "NSSearchPathForDirectoriesInDomains" is used to find documents in the user's documents directory expanding the tildes so we get the whole path. Using the "fileManager" object we check if the database exists or not, if it doesn't exists then we copy it to the user's phone from the application bundle. Method "copyDatabaseIfNeeded" is called from "applicationDidFinishLaunching". Once the database is copied to the user's phone, we need to display a list of coffee's from the database on the UITableView.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Getting data from the database&lt;/span&gt;&lt;br /&gt;The approach that I have taken here to get the data from the database is a little clean, as I have all my database operations in the Coffee Class. I have declared a class method in the "Coffee" class which is responsible to get the data from the database and fill the coffeeArray which is declared in the application delegate object (SQLAppDelegate).&lt;br /&gt;&lt;br /&gt;This is how the header file of the "Coffee" class will look like after the method decelerations are added.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;#import &amp;lt;sqlite3.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface Coffee : NSObject {&lt;br /&gt;&lt;br /&gt;NSInteger coffeeID;&lt;br /&gt;NSString *coffeeName;&lt;br /&gt;NSDecimalNumber *price;&lt;br /&gt;&lt;br /&gt;//Intrnal variables to keep track of the state of the object.&lt;br /&gt;BOOL isDirty;&lt;br /&gt;BOOL isDetailViewHydrated;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, readonly) NSInteger coffeeID;&lt;br /&gt;@property (nonatomic, copy) NSString *coffeeName;&lt;br /&gt;@property (nonatomic, copy) NSDecimalNumber *price;&lt;br /&gt;&lt;br /&gt;@property (nonatomic, readwrite) BOOL isDetailViewHydrated;&lt;br /&gt;&lt;br /&gt;//Static methods.&lt;br /&gt;+ (void) getInitialDataToDisplay:(NSString *)dbPath;&lt;br /&gt;+ (void) finalizeStatements;&lt;br /&gt;&lt;br /&gt;//Instance methods.&lt;br /&gt;- (id) initWithPrimaryKey:(NSInteger)pk;&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The method "getInitialDataToDisplay" gets the data from the database and creates "Coffee" objects using "initWithPrimaryKey" method and fills the objects in the coffeeArray which is declared in SQLAppDelegate.&lt;br /&gt;&lt;br /&gt;This is how the "getInitialDataToDisplay" method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;+ (void) getInitialDataToDisplay:(NSString *)dbPath {&lt;br /&gt;&lt;br /&gt;SQLAppDelegate *appDelegate = (SQLAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;&lt;br /&gt;if (sqlite3_open([dbPath UTF8String], &amp;amp;database) == SQLITE_OK) {&lt;br /&gt;&lt;br /&gt;const char *sql = "select coffeeID, coffeeName from coffee";&lt;br /&gt;sqlite3_stmt *selectstmt;&lt;br /&gt;if(sqlite3_prepare_v2(database, sql, -1, &amp;amp;selectstmt, NULL) == SQLITE_OK) {&lt;br /&gt;&lt;br /&gt;while(sqlite3_step(selectstmt) == SQLITE_ROW) {&lt;br /&gt;&lt;br /&gt;NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);&lt;br /&gt;Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey];&lt;br /&gt;coffeeObj.coffeeName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];&lt;br /&gt;&lt;br /&gt;coffeeObj.isDirty = NO;&lt;br /&gt;&lt;br /&gt;[appDelegate.coffeeArray addObject:coffeeObj];&lt;br /&gt;[coffeeObj release];&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;initWithPrimaryKey method is very simple and it looks like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (id) initWithPrimaryKey:(NSInteger) pk {&lt;br /&gt;&lt;br /&gt;[super init];&lt;br /&gt;coffeeID = pk;&lt;br /&gt;&lt;br /&gt;isDetailViewHydrated = NO;&lt;br /&gt;&lt;br /&gt;return self;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In "getInitialDataToDisplay" method we first get a reference to the application delegate because that is where the coffeeArray is declared. We open the database using sqlite3_open method which takes the database path and a database object. The database object is declared as static in the "Coffee.m" file.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import "Coffee.h"&lt;br /&gt;&lt;br /&gt;static sqlite3 *database = nil;&lt;br /&gt;&lt;br /&gt;@implementation Coffee&lt;br /&gt;...&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;After we open the connection to the database we create a select statement and if that returns "&lt;a target="_blank" href="http://www.sqlite.org/c3ref/c_abort.html"&gt;SQLITE_OK&lt;/a&gt;" we execute the select statement using sqlite3_step method, which will return "&lt;a target="_blank" href="http://www.sqlite.org/c3ref/c_abort.html"&gt;SQLITE_ROW&lt;/a&gt;" if the operation is a success and it has one or more rows to return. To get a full list of return codes &lt;a target="_blank" href="http://www.sqlite.org/c3ref/c_abort.html"&gt;click here&lt;/a&gt;. We then get the coffeeID, coffeename and create "Coffee" objects using "initWithPrimaryKey" method. When reading data from the database, the column index starts from zero instead of one. The coffee object is added to the array and we do this for n number of rows. If the connection to the database fails, only then we close the connection and release any resources associated with the connection object. The static database connection is left open to be used by the "Coffee" class.&lt;br /&gt;&lt;br /&gt;We close the database connection in the "finalizeStatements" method which is called from "applicationWillTerminate" which is in SQLAppDelegate.m file.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;+ (void) finalizeStatements {&lt;br /&gt;&lt;br /&gt;if(database) sqlite3_close(database);&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Now all we have to do is call the right methods from "applicationDidFinishLaunching" method in SQLAppDelegate.m file. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;//Copy database to the user's phone if needed.&lt;br /&gt;[self copyDatabaseIfNeeded];&lt;br /&gt;&lt;br /&gt;//Initialize the coffee array.&lt;br /&gt;NSMutableArray *tempArray = [[NSMutableArray alloc] init];&lt;br /&gt;self.coffeeArray = tempArray;&lt;br /&gt;[tempArray release];&lt;br /&gt;&lt;br /&gt;//Once the db is copied, get the initial data to display on the screen.&lt;br /&gt;[Coffee getInitialDataToDisplay:[self getDBPath]];&lt;br /&gt;&lt;br /&gt;// Configure and show the window&lt;br /&gt;[window addSubview:[navigationController view]];&lt;br /&gt;[window makeKeyAndVisible];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;To recap, we first copy the database to the user's phone if it does not exists, then we initialize the coffee array and get the initial data to display on the UITableView.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Display data in the UITableView&lt;/span&gt;&lt;br /&gt;Since the Coffee Array is in the application delegate file (SQLAppDelegate), for simplicity I' am going to add the "SQLAppDelegate.h" header file in "SQL_Prefix.pch" file so that the file is added to all the files in the project. This is how the file should look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#ifdef __OBJC__&lt;br /&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;#import "SQLAppDelegate.h"&lt;br /&gt;#endif&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Open "RootViewController.h" file and create a variable of type SQLAppDelegate like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class Coffee;&lt;br /&gt;&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;SQLAppDelegate *appDelegate;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We are able to do the above because "SQLAppDelegate.h" file is added as a header file to all the files in the project.&lt;br /&gt;&lt;br /&gt;Open "RootViewController.m" and import "Coffee.h" file, change the "viewDidLoad" method like this&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (void)viewDidLoad {&lt;br /&gt;[super viewDidLoad];&lt;br /&gt;&lt;br /&gt;self.navigationItem.rightBarButtonItem = self.editButtonItem;&lt;br /&gt;&lt;br /&gt;appDelegate = (SQLAppDelegate *)[[UIApplication sharedApplication] delegate];&lt;br /&gt;&lt;br /&gt;self.title = @"Coffee List";&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We get a reference to the application delegate in the second line and everything is self explanatory. Using the appDelegate we can access the array.&lt;br /&gt;&lt;br /&gt;Now all we have to do is tell the table view how many rows to expect and set the text property of the UITableViewCell which is returned in "cellForRowAtIndexPath" method.&lt;br /&gt;&lt;br /&gt;Method "numberOfRowsInSection" returns the number of rows UITableView should expect in a section. By default "numberOfSectionsInTableView" returns 1, so the UITableView looks like a regular table.&lt;br /&gt;&lt;br /&gt;Below is a code snippet of "numberOfRowsInSection"&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {&lt;br /&gt;return [appDelegate.coffeeArray count];&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;and cellForRowAtIndexPath&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;&lt;code&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt;static NSString *CellIdentifier = @"Cell";&lt;br /&gt;&lt;br /&gt;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&lt;br /&gt;if (cell == nil) {&lt;br /&gt;cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Get the object from the array.&lt;br /&gt;Coffee *coffeeObj = [appDelegate.coffeeArray objectAtIndex:indexPath.row];&lt;br /&gt;&lt;br /&gt;//Set the coffename.&lt;br /&gt;cell.text = coffeeObj.coffeeName;&lt;br /&gt;&lt;br /&gt;// Set up the cell&lt;br /&gt;return cell;&lt;br /&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;cellForRowAtIndexPat is called n number of times, where n is the total number of objects in the coffeeArray which is returned in "numberOfRowsInSection" method. We get the Coffee object from the array using "objectAtIndex" method and set the coffeeName as the text of the UITableViewCell.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;This concludes part one of the SQLite Tuturial, where we learn how easy it is to manage databases using SQLite Manager and using it in your iPhone applications. Overall SQLite is FREE for all to use. You also learn how to copy database to the user's phone and perform select operations on the database.&lt;br /&gt;&lt;br /&gt;The next tutorial will show you how to delete data.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Attachments&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/SQL.zip?attredirects=0"&gt;Download the source code used in this article&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-size:130%;" &gt;Suggested Readings&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html" target="_blank"&gt;SQLite Tutorial - Deleting data&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the SQLite database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;SQLite Tutorial - Displaying data in a UITableView.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-deleting-data.html"&gt;SQLite Tutorial - Deleting data from UITableView.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-adding-data.html"&gt;SQLite Tutorial - Inserting data into SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-loading-data-as.html"&gt;SQLite Tutorial - Loading data as required.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/11/sqlite-tutorial-updating-data.html"&gt;SQLite Tutorial - Updating data in SQLite database.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2009/02/sqlite-tutorial-saving-images-in.html"&gt;SQLite Tutorial - Saving images in the database&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-8763282710379412721?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/BVADkOKb-us" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/8763282710379412721/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=8763282710379412721&amp;isPopup=true" title="44 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8763282710379412721" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8763282710379412721" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/BVADkOKb-us/sqlite-tutorial-selecting-data.html" title="SQLite Tutorial - Selecting Data" /><author><name>jai</name><uri>http://www.blogger.com/profile/09514342500729931901</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17629479702229410159" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">44</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-5798500620870956761</id><published>2008-09-21T18:26:00.008-04:00</published><updated>2008-10-19T23:42:20.036-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Touches" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><title type="text">Multi Touch Tutorial - Part 4</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial I will show you how to implement the swipe feature (pan an image left or right).&lt;/span&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br/&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial.html"&gt;Touch Tutorial - Part One (touchesEnded Event)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-2.html"&gt;Touch Tutorial - Part Two (touchesBegan Event)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-3.html"&gt;Touch Tutorial - Part Three (Zoom In/Out)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;TouchTutorial - Part Four (pan left/right)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Welcome to the fourth part of the tutorial where we will see how to pan an image (move left or right). This tutorial borrows its source code from its predecessors.&lt;br /&gt;&lt;br /&gt;What we want to do is move the image left or right when the user swipes his fingers in either direction. We do this in touchesMoved method. This is how the source code will look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {&lt;br /&gt; &lt;br /&gt; if([timer isValid])&lt;br /&gt;  [timer invalidate];&lt;br /&gt; &lt;br /&gt; NSSet *allTouches = [event allTouches];&lt;br /&gt; &lt;br /&gt; switch ([allTouches count])&lt;br /&gt; {&lt;br /&gt;  case 1: {&lt;br /&gt;   //The image is being panned (moved left or right)&lt;br /&gt;   UITouch *touch = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;   CGPoint centerPoint = [touch locationInView:[self view]];&lt;br /&gt;   &lt;br /&gt;   [imgView setCenter:centerPoint];&lt;br /&gt;   &lt;br /&gt;  } break;&lt;br /&gt;  case 2: {&lt;br /&gt;   //The image is being zoomed in or out.&lt;br /&gt;   &lt;br /&gt;   UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;   UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];&lt;br /&gt;   &lt;br /&gt;   //Calculate the distance between the two fingers.&lt;br /&gt;   CGFloat finalDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]]&lt;br /&gt;                 toPoint:[touch2 locationInView:[self view]]];&lt;br /&gt;   &lt;br /&gt;   //Check if zoom in or zoom out.&lt;br /&gt;   if(initialDistance &gt; finalDistance) {&lt;br /&gt;    NSLog(@"Zoom Out");&lt;br /&gt;   }&lt;br /&gt;   else {&lt;br /&gt;    NSLog(@"Zoom In");&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  } break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Since only one touch is required to move the image left or right, the following code is executed when the total number of touches is one. We get the first touch and then get the position of the touch. We move the image by setting the position of the touch as the center of the UIImageView.&lt;br /&gt;&lt;br /&gt;I hope this tutorial helped you learning better how to use the touch features of the iPhone SDK. The same basic primniple can be used in any kind of application.&lt;br /&gt;&lt;br /&gt;The source code can be downloaded from &lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/MultiTouchTutorialPartFour.zip?attredirects=0"&gt;here&lt;/a&gt; and please leave me your comments.&lt;br /&gt;&lt;br /&gt;Happy Programing&lt;br /&gt;iPhone SDK Articles&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-5798500620870956761?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/FIl9lvvFDZA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/5798500620870956761/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=5798500620870956761&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/5798500620870956761" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/5798500620870956761" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/FIl9lvvFDZA/multi-touch-tutorial-part-4.html" title="Multi Touch Tutorial - Part 4" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-4.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-2370887102664445158</id><published>2008-09-21T17:52:00.009-04:00</published><updated>2008-10-19T23:41:14.293-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Touches" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><title type="text">Multi Touch Tutorial 3</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial I will show how to implement the pinch feature (zoom in/out).&lt;/span&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br/&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial.html"&gt;Touch Tutorial - Part One (touchesEnded Event)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-2.html"&gt;Touch Tutorial - Part Two (touchesBegan Event)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Touch Tutorial - Part Three (Zoom In/Out)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-4.html"&gt;TouchTutorial - Part Four (pan left/right)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In this tutorial, I will show you how to use the touchesMoved event to zoom in and out the image on the UIImageView. Now, I have not exactly figured out a way to actually zoom in and out the actual image but here is the code on when to zoom in and zoom out. If anyone has figured out a way to zoom in/out the actual image, please share it everyone.&lt;br /&gt;&lt;br /&gt;Before we can implement the touchesMoved event, we are going to declare some variables and methods in ImgViewController.h file. This is how the header file is going to look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@interface ImgViewController : UIViewController {&lt;br /&gt; &lt;br /&gt; IBOutlet UIImageView *imgView;&lt;br /&gt; NSTimer *timer;&lt;br /&gt; CGFloat initialDistance;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint;&lt;br /&gt;- (void) clearTouches;&lt;br /&gt;&lt;br /&gt;@end&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;disanceBetweenTwoPoints is used to calculate as the method name implies, distance between two points. initialDistance is used to keep track of the distance when touchesBegan method is fired. To zoom in and zoom out, we first need to calculate the distance between the two fingers and store it in initialDistance variable. This is how the touchesBegan method will look like.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {&lt;br /&gt; &lt;br /&gt; NSSet *allTouches = [event allTouches];&lt;br /&gt; &lt;br /&gt; switch ([allTouches count]) {&lt;br /&gt;  case 1: { //Single touch&lt;br /&gt;   &lt;br /&gt;   //Get the first touch.&lt;br /&gt;   UITouch *touch = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;   &lt;br /&gt;   switch ([touch tapCount])&lt;br /&gt;   {&lt;br /&gt;    case 1: //Single Tap.&lt;br /&gt;    {&lt;br /&gt;     //Start a timer for 2 seconds.&lt;br /&gt;     timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self &lt;br /&gt;                 selector:@selector(showAlertView:) userInfo:nil repeats:NO];&lt;br /&gt;     &lt;br /&gt;     [timer retain];&lt;br /&gt;    } break;&lt;br /&gt;    case 2: {//Double tap. &lt;br /&gt;     &lt;br /&gt;     //Track the initial distance between two fingers.&lt;br /&gt;     UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;     UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];&lt;br /&gt;     &lt;br /&gt;     initialDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]] &lt;br /&gt;                toPoint:[touch2 locationInView:[self view]]];&lt;br /&gt;    } break;&lt;br /&gt;   }&lt;br /&gt;  } break;&lt;br /&gt;  case 2: { //Double Touch&lt;br /&gt;   &lt;br /&gt;  } break;&lt;br /&gt;  default:&lt;br /&gt;  break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We get the first touch objects at index 0 and 1 and then we calculate the initial distance between the two points. This is how the distanceBetweenTwoPoints method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {&lt;br /&gt;&lt;br /&gt; float x = toPoint.x - fromPoint.x;&lt;br /&gt;    float y = toPoint.y - fromPoint.y;&lt;br /&gt;    &lt;br /&gt;    return sqrt(x * x + y * y);&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In touchesMoved event, we find out if there are at least two touches on the screen. We then get the touch object at index 0 and 1, calculate the distance between the finalDistance and the initialDistance. If the initialDistance is greater then the finalDistance then we know that the image is being zoomed out else the image is being zoomed in. This is how the source code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {&lt;br /&gt; &lt;br /&gt; if([timer isValid])&lt;br /&gt;  [timer invalidate];&lt;br /&gt; &lt;br /&gt; NSSet *allTouches = [event allTouches];&lt;br /&gt; &lt;br /&gt; switch ([allTouches count])&lt;br /&gt; {&lt;br /&gt;  case 1: {&lt;br /&gt;   &lt;br /&gt;  } break;&lt;br /&gt;  case 2: {&lt;br /&gt;   //The image is being zoomed in or out.&lt;br /&gt;   &lt;br /&gt;   UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;   UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];&lt;br /&gt;   &lt;br /&gt;   //Calculate the distance between the two fingers.&lt;br /&gt;   CGFloat finalDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]]&lt;br /&gt;                 toPoint:[touch2 locationInView:[self view]]];&lt;br /&gt;   &lt;br /&gt;   //Check if zoom in or zoom out.&lt;br /&gt;   if(initialDistance &gt; finalDistance) {&lt;br /&gt;    NSLog(@"Zoom Out");&lt;br /&gt;   } &lt;br /&gt;   else {&lt;br /&gt;    NSLog(@"Zoom In");&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  } break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;NSLog tells us if what we are doing is correct or not. If someone knows how to zoom in/out an actual image, please let me know.&lt;br /&gt;&lt;br /&gt;Since we keep track of the initialDistance, we need to clear that value when touches is canceled or when touches are ended. We do this in clearTouches method, which is called from touchesEnded event and touchesCanceled event. This is how the method looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)clearTouches {&lt;br /&gt;&lt;br /&gt; initialDistance = -1;&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I hope you found this tutorial a little helpful without the actual zoom in/out functionality. You can download the source code &lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/MultiTouchTutorialThree.zip?attredirects=0"&gt;here&lt;/a&gt; and please leave me your comments.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-2370887102664445158?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/6xThG4Rt1eE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/2370887102664445158/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=2370887102664445158&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2370887102664445158" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2370887102664445158" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/6xThG4Rt1eE/multi-touch-tutorial-3.html" title="Multi Touch Tutorial 3" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-3.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-7769137742833422632</id><published>2008-09-21T15:47:00.008-04:00</published><updated>2008-10-19T23:40:09.143-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Touches" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UIAlertView" /><title type="text">Multi Touch Tutorial Part 2</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial we will learn how to show a UIActionSheet by implementing touchesBegan method.&lt;/span&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br/&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial.html"&gt;Touch Tutorial - Part One (touchesEnded Event)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Touch Tutorial - Part Two (touchesBegan Event)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-3.html"&gt;Touch Tutorial - Part Three (Zoom In/Out)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-4.html"&gt;TouchTutorial - Part Four (pan left/right)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the second part of the touch tutorial series, I will show you how can you use the touchesBegan event. It is recommended that you read the first tutorial in this series. You can download the source code for the first tutorial here.&lt;br /&gt;&lt;br /&gt;This is the method which we will implement in ImgViewController.m file.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In this method we will display an alert if the user has touched the image for 2 seconds. This how the source code will look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {&lt;br /&gt; &lt;br /&gt; NSSet *allTouches = [event allTouches];&lt;br /&gt; &lt;br /&gt; switch ([allTouches count]) {&lt;br /&gt;  case 1: { //Single touch&lt;br /&gt;   &lt;br /&gt;   //Get the first touch.&lt;br /&gt;   UITouch *touch = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;   &lt;br /&gt;   switch ([touch tapCount])&lt;br /&gt;   {&lt;br /&gt;    case 1: //Single Tap.&lt;br /&gt;    {&lt;br /&gt;     //Start a timer for 2 seconds.&lt;br /&gt;     timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self &lt;br /&gt;                 selector:@selector(showAlertView:) userInfo:nil repeats:NO];&lt;br /&gt;     &lt;br /&gt;     [timer retain];&lt;br /&gt;    } break;&lt;br /&gt;    case 2: //Double tap.&lt;br /&gt;     break;&lt;br /&gt;   }&lt;br /&gt;  } break;&lt;br /&gt;  case 2: { //Double Touch&lt;br /&gt;   &lt;br /&gt;  } break;&lt;br /&gt;  default:&lt;br /&gt;  break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We get all the touches and for now we will only look at the code for single touch. Get the touch object at index 0 (since it is a single touch, there will be an object at this index) and find out the tap count. If the tap count is one then create a new timer for 2 seconds and give a method which will be called, when the timer is elapsed. The timer variable is declared in the header file of ImgViewController.h file. "showAlertView" is the method which is called when the user presses the screen for 2 seconds.&lt;br /&gt;&lt;br /&gt;To display an alert view, we need to implement the UIAlertViewDelegate. This is how the header file will be changed&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@interface ImgViewController : UIViewController {&lt;br /&gt; &lt;br /&gt; IBOutlet UIImageView *imgView;&lt;br /&gt; NSTimer *timer;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;this is how "showAlertView" method will look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;-(void) showAlertView:(NSTimer *)theTimer {&lt;br /&gt;&lt;br /&gt; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Birth of a star" message:@"Timer ended. Event Fired."&lt;br /&gt;               delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];&lt;br /&gt; [alert show];&lt;br /&gt; [alert release];&lt;br /&gt; &lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We do need to cancel the timer if any other method like touchesMoved, touchesEnded or touchesCanceled is called. We do this by first checking if the timer is active or not, if it is active then we call the "invalidate" method. This is to be done at the beginning of all the three methods mentioned.&lt;br /&gt;&lt;br /&gt;Run this application in the simulator and see it working. The same technique can be used to display an alert sheet or any custom action that you want to perform. &lt;br /&gt;&lt;br /&gt;You can download the source code from &lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/ApplicationPreferencesPart2.zip?attredirects=0"&gt;here&lt;/a&gt; and please leave me your comments.&lt;br /&gt;&lt;br /&gt;Happy Programming,&lt;br /&gt;iPhone SDK Articles&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-7769137742833422632?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/B550ZkYeK-I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/7769137742833422632/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=7769137742833422632&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7769137742833422632" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/7769137742833422632" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/B550ZkYeK-I/multi-touch-tutorial-part-2.html" title="Multi Touch Tutorial Part 2" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-2.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-8054300521009226235</id><published>2008-09-21T13:53:00.021-04:00</published><updated>2009-02-01T06:25:57.171-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Touches" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><title type="text">Multi Touch Tutorial</title><content type="html">&lt;span class="previewpost"&gt;Welcome to the first part of Multi Touch tutorial series. In this tutorial I will show you how you can respond to a tap event.&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;div&gt;&lt;div class="links_roundedcornr_box"&gt;&lt;div class="links_roundedcornr_top"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_content"&gt;&lt;ul&gt;&lt;li&gt;Touch Tutorial - Part One (touchesEnded Event)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-2.html"&gt;Touch Tutorial - Part Two (touchesBegan Event)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-3.html"&gt;Touch Tutorial - Part Three (Zoom In/Out)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial-part-4.html"&gt;TouchTutorial - Part Four (pan left/right)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="links_roundedcornr_bottom"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;First tutorial in this series, I will show how to zoom and image in and out. This is how the application will look like.&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/touchtutorial/partone/App.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://sites.google.com/site/iphonesdktutorials/images/touchtutorial/partone/App.jpg" alt="" border="0" /&gt;&lt;/a&gt;To get started, we have to&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a new project by selecting "Windows-based Application"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create a new UIView using IB and name it ImgView.&lt;/li&gt;&lt;li&gt;Create a new file in XCode by selecting File -&gt; New File -&gt; UIViewController sub class and name it "ImgViewController".&lt;/li&gt;&lt;li&gt;In IB, select File's owner object of the "ImgView" nib file and select Tools -&gt; Identity Inspector. Under Class Identity select "ImgViewContoller" as the class.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select Tools - &gt; Connections Inspector and create a connection from the view property to the view object in IB.&lt;/li&gt;&lt;li&gt;Place a UIImageView on the view we just created.&lt;/li&gt;&lt;li&gt;Add a &lt;a target="_blank" href="http://www.jpl.nasa.gov/wallpaper/art/pia05733-640-480.jpg"&gt;image&lt;/a&gt; to the resource folder, to be used by the UIImageView.&lt;/li&gt;&lt;li&gt;Select the Image and select Tools -&gt; Attributes Inspector in IB. From the Image drop down select your image.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Set the Mode to Center.&lt;/li&gt;&lt;li&gt;Un-check "User Interaction Enabled" and "Multiple Touch".&lt;/li&gt;&lt;li&gt;Select the view and select "Multiple Touch" in the Attributes Inspector. Note that "User Interaction Enabled" should already be checked, if not check it.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Using the last two settings all the touches events will be sent to ImgViewController. Since we need to control the image, we need a variable of type UIImageView. This is how the header file of "MultiTouchTutorialAppDelegate" will look like.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;#import &amp;lt;UIKit/UIKit.h&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;@class ImgViewController;&lt;br /&gt;&lt;br /&gt;@interface MultiTouchTutorialAppDelegate : NSObject &lt;UIApplicationDelegate&gt; {&lt;br /&gt;    UIWindow *window;&lt;br /&gt; ImgViewController *ivController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UIWindow *window;&lt;br /&gt;&lt;br /&gt;@end&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Using IB, select File's owner object and open Tools -&gt; Connections Inspector. Create a connection from the imgView to the UIImageView placed on the view. Now we will be able to control the UIImageView from code.&lt;br /&gt;&lt;br /&gt;Now we need to add the view "ImgView" as a subview in applicationDidFinishLaunching method. This is how the source code will look like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {    &lt;br /&gt;&lt;br /&gt; ivController = [[ImgViewController alloc] initWithNibName:@"ImgView" bundle:[NSBundle mainBundle]];&lt;br /&gt; &lt;br /&gt; [window addSubview:[ivController view]];&lt;br /&gt; &lt;br /&gt;    // Override point for customization after application launch&lt;br /&gt;    [window makeKeyAndVisible];&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Click on Ctrl+return to run the application in simulator. You should see the image loaded in the simulator.&lt;br /&gt;&lt;br /&gt;Right now the application does not respond to any events, but all we have to do is implement some methods. Let's implement the touchesEnded method which will be called when touches are ended.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { &lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In this method we will respond to a single tap and double tap. On single tap we will zoom out the image and on double tap we will set the mode to "Center", which is doing the same as in step 9.&lt;br /&gt;&lt;br /&gt;This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { &lt;br /&gt; &lt;br /&gt; //Get all the touches.&lt;br /&gt; NSSet *allTouches = [event allTouches];&lt;br /&gt; &lt;br /&gt; //Number of touches on the screen&lt;br /&gt; switch ([allTouches count])&lt;br /&gt; {&lt;br /&gt;  case 1:&lt;br /&gt;  {&lt;br /&gt;   //Get the first touch.&lt;br /&gt;   UITouch *touch = [[allTouches allObjects] objectAtIndex:0];&lt;br /&gt;   &lt;br /&gt;   switch([touch tapCount])&lt;br /&gt;   {&lt;br /&gt;    case 1://Single tap&lt;br /&gt;     imgView.contentMode = UIViewContentModeScaleAspectFit;&lt;br /&gt;     break;&lt;br /&gt;    case 2://Double tap.&lt;br /&gt;     imgView.contentMode = UIViewContentModeCenter;&lt;br /&gt;     break;&lt;br /&gt;   }&lt;br /&gt;  } &lt;br /&gt;  break;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We get all the touches from the event into allTouches variable. We thenfind out how many fingers were touching the screen, since in our case we only want to zoom in and out, it seems normal to assume that the user will only be using one finger. We then find out how many tocuhs are touching the screen by calling the count method of allTouches variable. If there is only one finger touching the screen, we get the Touch object at index zero and find out the tap count of that object. If the tap count is one we will zoom out the image and if it is two we are going to zoom in. We zoom out the image by setting the contentMode to UIViewContentModeScaleAspectFit and zoom in the image by setting it to UIViewContentModeCenter.&lt;br /&gt;&lt;br /&gt;In this tutorial we learnt how to respond to touchesEnded event and in the ftuture tutorials we will learn ho wto respond to touches began, touches moved and touches cancelled.&lt;br /&gt;&lt;br /&gt;You can download the source code for this tutorial &lt;a target="_blank" href="http://sites.google.com/site/iphonesdktutorials/sourcecode/MultiTouchTutorialPartOne.zip"&gt;here&lt;/a&gt;. Please leave me your comments and let me know your thoughts.&lt;br /&gt;&lt;br /&gt;Happy Programming&lt;br /&gt;iPhone SDK Articles&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-8054300521009226235?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/7LbWteJQWss" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/8054300521009226235/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=8054300521009226235&amp;isPopup=true" title="15 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8054300521009226235" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/8054300521009226235" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/7LbWteJQWss/multi-touch-tutorial.html" title="Multi Touch Tutorial" /><author><name>jai</name><uri>http://www.blogger.com/profile/09514342500729931901</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17629479702229410159" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">15</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/09/multi-touch-tutorial.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-9017208940051771851.post-2458696480069070565</id><published>2008-09-16T23:00:00.023-04:00</published><updated>2009-01-19T00:40:56.701-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone SDK Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="UITableView" /><category scheme="http://www.blogger.com/atom/ns#" term="UIToolbar" /><title type="text">Navigation Controller + UIToolbar</title><content type="html">&lt;span class="previewpost"&gt;In this tutorial we will learn how to add a UIToolbar to an app with UINavigationController.&lt;/span&gt; &lt;br /&gt;&lt;span class="fullpost"&gt;In this tutorial we will learn how to add a UIToolbar to an app with UINavigationController. I had a requirement where I wanted to add a UIToolbar with one button. Clicking the button will load a view controller which is the same view controller when a UITableViewCell is selected and this is what I did.&lt;br /&gt;&lt;br /&gt;This is how the final app will look like&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/iphonesdktutorials/images/navtoolbar/App.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://sites.google.com/site/iphonesdktutorials/images/navtoolbar/App.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Start by creating a new project by selecting "Navigation-Based Application". Open the header file of "RootViewController" and create a variable of type UIToolbar and UINavigationController. This is how the file should look like, without the comments. We also create two variables of the same UIViewController and this will be explained later.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@class InfoViewController;&lt;br /&gt;&lt;br /&gt;@interface RootViewController : UITableViewController {&lt;br /&gt;&lt;br /&gt;UIToolbar *toolbar;&lt;br /&gt;InfoViewController *ivControllerToolbar;&lt;br /&gt;InfoViewController *ivControllerCell;&lt;br /&gt;UINavigationController *infoNavController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Open the implementation file and write the following code in viewWillAppear method. This is the method which is always called when the view is going to appear.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)viewWillAppear:(BOOL)animated {&lt;br /&gt; [super viewWillAppear:animated];&lt;br /&gt;&lt;br /&gt;//Initialize the toolbar&lt;br /&gt;toolbar = [[UIToolbar alloc] init];&lt;br /&gt;toolbar.barStyle = UIBarStyleDefault;&lt;br /&gt;&lt;br /&gt;//Set the toolbar to fit the width of the app.&lt;br /&gt;[toolbar sizeToFit];&lt;br /&gt;&lt;br /&gt;//Caclulate the height of the toolbar&lt;br /&gt;CGFloat toolbarHeight = [toolbar frame].size.height;&lt;br /&gt;&lt;br /&gt;//Get the bounds of the parent view&lt;br /&gt;CGRect rootViewBounds = self.parentViewController.view.bounds;&lt;br /&gt;&lt;br /&gt;//Get the height of the parent view.&lt;br /&gt;CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);&lt;br /&gt;&lt;br /&gt;//Get the width of the parent view,&lt;br /&gt;CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);&lt;br /&gt;&lt;br /&gt;//Create a rectangle for the toolbar&lt;br /&gt;CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);&lt;br /&gt;&lt;br /&gt;//Reposition and resize the receiver&lt;br /&gt;[toolbar setFrame:rectArea];&lt;br /&gt;&lt;br /&gt;//Create a button&lt;br /&gt;UIBarButtonItem *infoButton = [[UIBarButtonItem alloc]&lt;br /&gt;        initWithTitle:@"Info" style:UIBarButtonItemStyleBordered target:self action:@selector(info_clicked:)];&lt;br /&gt;&lt;br /&gt;[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];&lt;br /&gt;&lt;br /&gt;//Add the toolbar as a subview to the navigation controller.&lt;br /&gt;[self.navigationController.view addSubview:toolbar];&lt;br /&gt;&lt;br /&gt;//Reload the table view&lt;br /&gt;[self.tableView reloadData];&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Start by initializing the toolbar and then calculate some values. These values determine the position and the width/height of the toolbar. A button is created which will be added to the the toolbar and when the button is clicked "info_cancel" method is called. The button are added from LTR. The toolbar is then added as a subview to the navigation controller.&lt;br /&gt;&lt;br /&gt;Add a new view using IB and I have named it "InfoView". Create a UIViewController in XCode and name it InfoViewController and assign this class as the class to be used by the InfoView nib file. Declare a Boolean property in InfoViewController called "isViewPushed" which will be true when a view is pushed to the top of the stack and false when the view is presented as a modal view. Based on the value of this variable we add a cancel button when the view is loaded as a modal view.&lt;br /&gt;&lt;br /&gt;This is how the info button will look like when clicked&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void) info_clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;//Initialize the Info View Controller&lt;br /&gt;if(ivControllerToolbar == nil)&lt;br /&gt;ivControllerToolbar = [[InfoViewController alloc] initWithNibName:@"InfoView" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt;ivControllerToolbar.isViewPushed = NO;&lt;br /&gt;&lt;br /&gt;//Initialize the navigation controller with the info view controller&lt;br /&gt;if(infoNavController == nil)&lt;br /&gt;infoNavController = [[UINavigationController alloc] initWithRootViewController:ivControllerToolbar];&lt;br /&gt;&lt;br /&gt;//Present the navigation controller.&lt;br /&gt;[self.navigationController presentModalViewController:infoNavController animated:YES];&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;From the header file we know that we have declared two types of ViewControllers for the same nib file, this is because for some reason having one variable to control the same view controller results in some unexpected behavior. When the info button is clicked we first initialize the ivControllerToolbar, then we initialize the infoNavController with the ivControllerToolbar view controller. Finally, we present the infoNavController using "presentModalViewController" method of the navigationController. If we do not do this, then the infoview will be loaded without a navigation controller and we will have no graceful way of getting back to the RootViewController. Also, notice that we tell the infoviewcontroller explicitly that the controller is not pushed. This variable will be used in viewDidLoad method of the InfoViewController.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt; if(isViewPushed == NO) {&lt;br /&gt;&lt;br /&gt;self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]&lt;br /&gt;           initWithBarButtonSystemItem:UIBarButtonSystemItemCancel&lt;br /&gt;           target:self action:@selector(cancel_Clicked:)] autorelease];&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Here we check if the view is pushed it is only then we add the cancel button to the left bar button item. When the button is clicked "cancel_Clicked" method is called which will dismiss the modal view presented. This is how the code looks like&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;-(void) cancel_Clicked:(id)sender {&lt;br /&gt;&lt;br /&gt;[self.navigationController dismissModalViewControllerAnimated:YES];&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Since, this is a table view a user can select a row and go to its detail view. We have some sample and this is how the didSelectRowAtIndexPath method will look like.&lt;br /&gt;&lt;br /&gt;&lt;div class="rbroundbox"&gt;&lt;div class="rbtop"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="rbcontent"&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt; // Navigation logic -- create and push a new view controller&lt;br /&gt;&lt;br /&gt;//Initialize the info view controller.&lt;br /&gt;if(ivControllerCell == nil)&lt;br /&gt;ivControllerCell = [[InfoViewController alloc] initWithNibName:@"InfoView" bundle:[NSBundle mainBundle]];&lt;br /&gt;&lt;br /&gt;ivControllerCell.isViewPushed = YES;&lt;br /&gt;&lt;br /&gt;//Push the view controller to the top of the stack.&lt;br /&gt;[self.navigationController pushViewController:ivControllerCell animated:YES];&lt;br /&gt;}&lt;/div&gt;&lt;div class="rbbot"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;First we initialize the info view controller called "ivControllerCell" which is specifically used to load the same view controller in didSelectRowAtIndexPath method. This time we tell the info view controller that the view will be pushed to the top of the stack.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is the easiest way I found to add a UIToolbar to an application with UINavigationController. You can download the source code &lt;a href="http://sites.google.com/site/iphonesdktutorials/sourcecode/UINavigationControllerWithToolbar.zip" target="_blank"&gt;here&lt;/a&gt; and please leave me your comments.&lt;br /&gt;&lt;br /&gt;Happy Programming&lt;br /&gt;iPhone SDK Articles&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9017208940051771851-2458696480069070565?l=www.iphonesdkarticles.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/iPhoneSDKArticles/~4/pm906-8peqI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.iphonesdkarticles.com/feeds/2458696480069070565/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9017208940051771851&amp;postID=2458696480069070565&amp;isPopup=true" title="23 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2458696480069070565" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9017208940051771851/posts/default/2458696480069070565" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/iPhoneSDKArticles/~3/pm906-8peqI/navigation-controller-uitoolbar.html" title="Navigation Controller + UIToolbar" /><author><name>iPhone SDK Articles</name><uri>http://www.blogger.com/profile/08386394388537674897</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16542777069554124446" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">23</thr:total><feedburner:origLink>http://www.iphonesdkarticles.com/2008/09/navigation-controller-uitoolbar.html</feedburner:origLink></entry></feed>
