I’m going to build this tutorial on the previous two so if you haven’t checked them out yet, you can see the first one here and the second one here. You can also download the source code on the bottom of each tutorial.
What we’ve done so far
We used UITableViewController to build out our root view controller that lists all the DVDs from our data file. Then we customized each cell by adding a DVD cover and some basic info about each movie. Tapping a row in the table caused the app to go to a detail page which was also a table displaying expanded info about the selected movie. That’s the part we’re going to work on now.
1. Download some source code to get your started
Since we’re going to be completely removing the detail view controller we used in the previous tutorials, let’s just start from there. Instead of walking you through deleting the controller and removing the appropriate functionality, download this source code that will get you started. You’ll get the root view controller with customized cells in it. However, tapping on any of the rows won’t do anything, yet. Download the primer project here: MyDVDLibrary03Primer.
2. Enhance test data file
Since our test data file only contains title, length, image and release date for each movie, that’s not going to cut it when trying to design a detail view page. We’ll at least want to add the description of the movie and maybe also its genre. This can be very tedious to do in a plist like we’re using right now but it will get a lot easier once we start using Core Data that I will cover in later tutorials.
I won’t make you add all the data by hand so for a shortcut, download the completed plist file here and replace your existing one that can be found in Xcode under the Resources folder: TestData.plist.
3. Create new DetailViewController class
In Xcode’s file browser on the left, right-click on the Classes folder and choose Add -> New File… . Under Cocoa Touch Classes group choose UIViewController subclass and make sure to check the With XIB for user interface checkbox. This will not only create our subclass but also the NIB file that we’ll use to layout our UI components.
4. Set up UI outlets
We now need to set up all properties in our controller that will be used on the detail view page. There will be an image view for the DVD cover, a label for the title, release date, length, genre and a text view for the description. Add this to the header file of the DetailViewController (DetailViewController.h):
@interface DetailViewController : UIViewController { IBOutlet UIImageView *coverImageView; IBOutlet UILabel *titleLabel; IBOutlet UILabel *releaseDateLabel; IBOutlet UILabel *lengthLabel; IBOutlet UILabel *genreLabel; IBOutlet UITextView *descriptionTextView; } @property (nonatomic, retain) UIImageView *coverImageView; @property (nonatomic, retain) UILabel *titleLabel; @property (nonatomic, retain) UILabel *releaseDateLabel; @property (nonatomic, retain) UILabel *lengthLabel; @property (nonatomic, retain) UILabel *genreLabel; @property (nonatomic, retain) UITextView *descriptionTextView; @end
Synthesize the properties in the implementation file (DetailViewController.m):
@synthesize coverImageView, titleLabel, releaseDateLabel, lengthLabel, genreLabel, descriptionTextView;5. Lay out and connect UI components in Interface Builder
Before we jump to Interface Builder make sure to save all the changes so that IB can pick up on them.
In Xcode, locate DetailViewController.xib file (it got created this file along with DetailViewController class in Step#3) and double-click on it. Once Interface Builder opens you should see an empty canvas where we’re going to place our UI elements. Lay them out as shown in the screenshot below. Note that you should uncheck Editable checkbox on your text view so that the text is read-only.

Now we need to connect the UI elements to its variable counterparts. I’m not going to cover step-by-step how to do that as it has been discussed in some detail in the tutorial on customizing view cells. Please, review that tutorial if you’re unclear how to follow the next set of instructions.
Click on File’s Owner icon to highlight it. From the file menu choose Tools -> Connections Inspector (Cmd + 2). Under Outlets, you’ll see all of our instance variables we declared in the DetailViewController class. Control-drag from File’s Owner to each UI component in the view to connect coverImageView to Image View, releaseDateLabel to Release Date label, genreLabel to Genre label, etc. Once done, your Connections Inspector should be set up like this:

Save your changes and return back to Xcode.
6. Prepare DetailViewController to read test data
If you recall what we did with the original DetailViewController when it was still a table, in its initialization method we passed in a dictionary containing all the info about our DVD library. This was read in using DvdLibraryDao object that basically took the plist we constructed earlier and put all its content into a dictionary. We’re going to do the same thing in our new DetailViewController, only we’re now adding a couple of properties (genre, description) that we just added in Step#2.
We also add declaration of our custom initialization method here. It’s pretty much just a modified initWithNibName method that adds dvdData into the mix. This method will set the local instance variable dvdData that is also declared here. Change DetailViewController.h header file to look like this:
@interface DetailViewController : UIViewController { IBOutlet UIImageView *coverImageView; IBOutlet UILabel *titleLabel; IBOutlet UILabel *releaseDateLabel; IBOutlet UILabel *lengthLabel; IBOutlet UILabel *genreLabel; IBOutlet UITextView *descriptionTextView; NSDictionary *dvdData; } @property (nonatomic, retain) UIImageView *coverImageView; @property (nonatomic, retain) UILabel *titleLabel; @property (nonatomic, retain) UILabel *releaseDateLabel; @property (nonatomic, retain) UILabel *lengthLabel; @property (nonatomic, retain) UILabel *genreLabel; @property (nonatomic, retain) UITextView *descriptionTextView; - (id)initWithDvdData:(NSDictionary *)dvdData nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; @end
Switch over to DetailViewController.m implementation file. Let’s implement the initWithDvdData method:
- (id)initWithDvdData:(NSDictionary *)data nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { dvdData = data; } return self; }
All this is doing is it assigns data that is passed in to our instance variable dvdData.
To read everything in from dvdData to all of the UI elements, we’ll insert a little snippet of code in the viewDidLoad delegate method. As you can see, we assign each value from dvdData to its corresponding UI element.
- (void)viewDidLoad { coverImageView.image = [UIImage imageNamed:[dvdData valueForKey:@"coverImage"]]; titleLabel.text = [dvdData valueForKey:@"title"]; releaseDateLabel.text = [NSString stringWithFormat:@"%@", [dvdData valueForKey:@"releaseDate"]]; lengthLabel.text = [NSString stringWithFormat:@"%@ minutes", [dvdData valueForKey:@"featureLength"]]; genreLabel.text = [dvdData valueForKey:@"genre"]; descriptionTextView.text = [dvdData valueForKey:@"description"]; [super viewDidLoad]; }
7. Handle didSelectRowAtIndexPath in RootViewController
Now that we have our detail view controller all ready to go, let’s connect the dots and have the RootViewController go to the detail page when a row is tapped.
In RootViewController.m, locate the didSelectRowAtIndexPath method. Just as we did before, we’ll instantiate DetailViewController here and push it to the controller stack:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { DetailViewController *controller = [[DetailViewController alloc] initWithDvdData:[dao libraryItemAtIndex:indexPath.row] nibName:@"DetailViewController" bundle:[NSBundle mainBundle]]; controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"title"]; [self.navigationController pushViewController:controller animated:YES]; [controller release]; }
If everything went well, you should be able to run your project and get something like this:
8. Format the release date field
While something like 2007-07-08 16:32:07 -0700 is completely acceptable by me, many people want to see something a bit more user friendly. Let’s take that date and try to display it as July 8, 2007. We’re going to achieve that using a nifty utility class called NSDateFormatter. Open DetailViewController.m and change viewDidLoad method to look like this:
- (void)viewDidLoad { coverImageView.image = [UIImage imageNamed:[dvdData valueForKey:@"coverImage"]]; titleLabel.text = [dvdData valueForKey:@"title"]; lengthLabel.text = [NSString stringWithFormat:@"%@ minutes", [dvdData valueForKey:@"featureLength"]]; genreLabel.text = [dvdData valueForKey:@"genre"]; descriptionTextView.text = [dvdData valueForKey:@"description"]; // Format date we get from releaseDate field to more readable form NSDate *releaseDate = (NSDate *)[dvdData valueForKey:@"releaseDate"]; NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; [dateFormatter setDateFormat:@"MMMM d, YYYY"]; releaseDateLabel.text = [dateFormatter stringFromDate:releaseDate]; [super viewDidLoad]; }
All we had done is gave our formatter a string representation of the date format we want and then outputted that date to releaseDateLabel.
Conclusion
When customizing your detail views, possibilities are endless. You could add a texture to your background, add more images, maybe a table with some detailed information, or other controls that would take you forward in the controller stack. But I hope this tutorial got you started and showed you some basic techniques and tricks to create a detail page.
You can download the complete source code to this tutorial here: My DVD Library Tutorial 3




This is great! Thanks so much!
Do you have any direction on having the detail view be a tab bar with xibs per tab? I have that working right now but I cannot seem to attach the data from the plist to a tab item. When I click the tab item it shows null.
How can I change the data available to the tabs based on the row selection?
[...] the rest here: Create a Detail View Page using UIImageView, UITextView and UILabel Share and [...]
The next tutorial I’ll be writing will be on tabbed controller, so stay tuned…
Thanks for the info. Is it possible to have a text wrap around the image? Like typical word document or magazine article?
Hi !
I would want to know HOW I can make a REQUEST,
for testData.plist can show only : Genre = Action
And where I must put this code line ?
Thanks very much
Best regards
Excuse my bad english !!!
Hey is it possible to in the DetailViewController to add a Button to open a url?
So in the .h I would add:
IBOutlet UIButton *websiteButton;
and
@property (nonatomic, retain) UIButton *websiteButton;
and in the .m I would add somthing in here and link it though IB Builder?
- (void)viewDidLoad {
coverImageView.image = [UIImage imageNamed:[dvdData valueForKey:@"coverImage"]];
titleLabel.text = [dvdData valueForKey:@"title"];
lengthLabel.text = [NSString stringWithFormat:@"%@ minutes", [dvdData valueForKey:@"featureLength"]];
genreLabel.text = [dvdData valueForKey:@"genre"];
descriptionTextView.text = [dvdData valueForKey:@"description"];
??????????????????????????????????????????
// Format date we get from releaseDate field to more readable form
NSDate *releaseDate = (NSDate *)[dvdData valueForKey:@"releaseDate"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"MMMM d, YYYY"];
releaseDateLabel.text = [dateFormatter stringFromDate:releaseDate];
[super viewDidLoad];
}
Also could the same be done for phone numbers?
Thanks
Matt
Hey Matt, opening URLs is quite easy, actually. Whether it’d be via a button or some other UI element. This call will open any URL you provide: [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://apple.com"]]; To dial a phone number, use tel:// scheme instead of http://.
Thank-you very much for sharing your expertise. Could you PLEASE adapt this tutorial for a SplitView Controller
When i download this primer and try to run it i get an error “error: There is no SDK with the name or path ‘iphoneos3.0′”. I fix this by going to Project>Edit project settings>Base sdk for all configurations. By default its blank, I change that to read “Latest iOS”. Is this the correct solution? Then when i try to build i get the following error:
“Code Sign error: The identity ‘iPhone Developer’ doesn’t match any valid certificate/private key pair in the default keychain”
Does anyone have any idea on how to fix this?
Thanks
The answer to my above question is to then choose simulator in the drop down menu in the upper left corner of xcode. For certain samples mine defaults to device.
Thanks, I was working on something just like this for class. This really helped me out.
i gonna do applicaiton like this i got around 5 000 words as a table view and as second view their info plist is enough for storing their data? or must i use sqlite or something else? also i wanna use coredata to manage is it posible if i use plist?
Hi, I am working on an App which follow from your tutorial. The app reads the plist and have the tableView and Detail view.
The plist has the latitude & longitude data. how can I read this data and show on the MapView. When I click the Map button on the Detail View.
I don’t know what is the problem when I read the data, the NSLog the console result always show null or 0.00000.
Hope someone can help me for this!
Thanks!!!
You are my Hero!!! Helped a lot!!! I love you!!!
Thank you! Is it possible to make TableView Sectioned by genre plz?
Uvajaemiy Vladimir Olexa ! Podskajite pojaluysta kak sdelat’ sections dlya TableView po Ganram iz plist? spasibo Vam bolshoe za otlichniy primer! S uvajeniem bidloCoder Konstantin )
when i did this for storyboards it’s not working well . when i select Cell in tableView its not passing the data into detail view .
in detail view it showing just null; Plzzzzz Help me. I will BE Very Greatfull For this Help; Thank you.
could any one help me to save uitextview content in photo gallery
anyone can help me for,
when we have to click on cover image in detail view ,
at that time we can get the large image view with navigation in anotherView displaying.
I need to make an array to alphabetize the dvds so I can add an index. so It would be first an array with the alphabet then each movie in its correct letter. I can’t figure this out can anyone please help me? This is prett urgent. Thank you!!
Leave a Reply