iOS

Improve the Recipe App With a Better Detail View Controller


Several weeks ago, we showed you how to use Segue in Storyboard to pass data between different view controllers. We’ve built a simple app to display a list of recipes. When user taps on any of the recipes, the app navigates to a detailed view and brings up the recipe name. This is very simple app. But if you understand how it works, this is the foundation to help you advance into a full-fledge iOS developer.

After publishing the tutorial, I got lots of requests to improve the detail view. The original detail view is primitive with the recipe name only. How can we improve it and display more information such as the preparation time, ingredient and the dish photo? In this tutorial, we’ll work on it together and make a better app. Before we move on, however, make sure you check out the below tutorial:

You have to understand the basic OOP concept before you can work on this tutorial. If you haven’t done so, take some time and read through the article. You can’t become a full-fledged iOS developer without learning objects and classes.

The Final Deliverable

To give you an idea about the improvement, let’s first take a look at the final deliverable. As you can see from the sample screenshot, the revamped Recipe app shows user detailed information about a recipe.

recipe app with improved detail view

Recipe app with improved detail view

Revisit the Segue Data Passing

Storyboard Segue Identifier

Storyboard Segue Identifier

In the Segue tutorial, we explained how to make use of Segue to pass the recipe name from the list view to the detail view. Here is the code:

We simply set the property (i.e. recipeName) in the RecipeDetailViewController to pass the recipe name. Obviously, you can add other properties in the detail view controller to pass other recipe-related values. However, this is not the best practice. If you’ve read the OOP tutorial, you know it’s better to create a Recipe class and group all the properties within the class.

Let’s Get Started

First, download this Xcode project. You’ll use this project as a baseline to build the app.

Creating a Recipe Class

We’ll first create the Recipe Class. Right click on RecipeBook folder and select “New File…”. Choose the “Objective-C class” template (under Cocoa Touch) and click “Next”. Name the class as “Recipe” and as a subclass of “NSObject”. Click “Next” and save the file in your Xcode project folder.

Create the Recipe Class

Create the Recipe Class with NSObject as subclass

Once completed, Xcode will create the Recipe.h and Recipe.m files. In the header file, add the properties of the Recipe class:

In the implementation file (i.e. Recipe.m), we add the @synthesis directive. The @synthesize directive tells the compiler to generate the setters and getters for accessing the properties we define in the header.

Now we’ve created a Recipe class with various properties including recipe name, preparation time, image and ingredients. Later we’ll make use of it to instantiate different recipe objects and pass it to the detail view controller.

Populate the Recipe Data

To keep thing simple, we’ll populate the recipe data right in the “RecipeBookViewController”. In real app, this kind of data are usually stored in property list file or database.

In the “viewDidLoad” method of “RecipeBookViewController.m”, we initialize the Recipe objects (with different preparation time, ingredients, etc) and put them into the “recipes” array.

Redesign the Detail View Controller

Originally, the detail view controller only displays the name of recipe. We’re going to revamp it to show users more information about a recipe. First, download this image pack and add all the images to the projects.

Recipe Images Added

Add the Recipe Photos to the Project

What’s @2x image?

Since the release of iPhone 4 with Retina display, your app should prepare to support different screen resolutions (i.e. 320×480 for older generation of iPhone and 640×960 for iPhone 4 or later). Apple has made it fairly easy for iOS developers to support multiple resolutions. Applications should include two separate files for each image resource. One file provides a standard-resolution version of a given image, and the second provides a high-resolution version of the same image. The naming conventions for each pair of image files is as follows:

Standard: <ImageName>.<filename_extension>
High resolution: <ImageName>@2x.<filename_extension>

The UIImage class handles all of the work needed to load high-resolution images into your application. When you load an image with UIImage, it automatically determine the screen resolution and loads the corresponding image file. For instance,

The above code will load “[email protected]” on device with high resolution. While on the standard screen resolution, it loads up the “photo-frame.png”.

Select the Storyboard and locate the “Recipe Detail View Controller”. First and foremost, delete the “Label” component and add an image view to the detail view. Set the width and height of the image view to 297 and 199 respectively.

Detail View - Add Image View

Detail View – Add Image View

Select the attribute inspector and set the image to “photo-frame.jpg”. As you set the image, it’ll be automatically loaded and displayed in the Storyboard. This image is used to display a photo frame for the recipe photo.

Detail View - Photo Frame

Detail View – Photo Frame

Next, we add another image view that serves as a placeholder of the recipe photo. Drag the image view from the Object Library and place it over the photo frame like the screen shown below.

Detail View - Recipe Photo Image View

Image View for Recipe Photo

Now, add a label and change the text to “Ingredients”. In the attribute inspector, you can change the font size and type by altering the “Font” option. Just use the default system font or pick the one you like. Next, add another label for preparation time. Lastly, drag the Text View object to the view. The Text View is an UI element for displaying multiple lines of text. We’ll use it to display the list of ingredient. Below is the screenshot for your reference:

Detail View - Label and Text View

Detail View – Label and Text View

Establish the Connection Between Variables and UI Elements

With the redesigned interface, we’ll establish the connection between our code and the UI elements. In the Storyboard, select the “Recipe Detail View Controller” and switch to the Assistant Editor.

Show Assistant Editor

Show Assistant Editor and Hide Utility Area

Press and hold the control key, click the image view and drag it towards the “RecipeDetailViewController.h”. As you place the pointer between the “@interface” and “@end” keywords, you should see a prompt that allows you to insert an outlet. Name the outlet variable as “recipePhoto”.

Detail View - Establish Variable Connection

Detail View – Establish Variable Connection

Repeat the same step for the “PrepTime” label and Text View. Name the outlet of PrepTime label as “prepTimeLabel” and that of text view as “ingredientTextView”. Lastly, add a property for recipe. This property allows other controllers to pass the recipe details. After all the changes, the RecipeDetailViewController.h should like this:

In the viewDidLoad method of the RecipeDetailViewController.m, change it to the following code:

Here, we add code to setup the Recipe Detail View. Line 5 of the code alters the title of navigation bar to the name of recipe. Line 6 and 7 configure the preparation time label and set the recipe photo.

Line 9 to 13 turns the ingredients array into multiple lines of text for the ingredient text view. The “\n” character is an escape character to say “Put a carriage return here”. In other words, it’s a new line indicator.

Passing Recipe to Detail View Controller

As we’ve learnt in the Segue tutorial before, Segues manages the transition between view controllers. When a segue is triggered, before the visual transition occurs, the storyboard runtime invokes prepareForSegue:sender: method of the current view controller. By implementing this method, we can pass any needed data to the view controller that is about to be displayed. Here, we’ll pass the selected recipe object to the detail view controller.

In the prepareForSegue method of RecipeBookViewController.m, change the code to:

Line 5 of the above code determines the selected recipe (base on the indexPath) and passes it to the Recipe Detail View Controller (i.e. the destViewController variable).

Run the App

You’ve made it! The final step is to execute the app and see how it works. If your app can run properly, it should give you a much polished Recipe Details.

recipe app with improved detail view

Recipe app with improved detail view

What’s Next?

I hope you enjoy the tutorial and love the app you just built. It’s not a complex app but it covers some of the most common UI elements such as navigation controller and tab bar controller. Don’t wait for the next tutorial to show you what to do next. I encourage you to tweak the app and make it even better. Say, use a table view (instead of text view) to list out all ingredients or add a new tab item. As I said before, you can’t become a good programmer by just reading a book or this tutorial. You have to explore, make mistake and most importantly code! So base on what you’ve learnt, tweak the app and turn it into your own.

As always, leave us comment to share your thought.

Update: You can download the source code of the Xcode project from here.

iOS
A Beginner’s Guide to Access Levels in Swift
Tutorial
A Beginner’s Guide to Bezier Paths and Shape Layers
Swift
Protocol Oriented Programming in Swift: Is it better than Object Oriented Programming?
  • Bubumuk

    BubumukBubumuk

    Author Reply

    It looks great! Thank you.


  • Toby Powell

    your tutorials and site are fantastic! you do a great job of explaining the concepts, this is absolutely my favorite ios site, i’ve got a ton of books and done a ton of video tutorials but your tutorials really clarify the topics, thanks Simon, keep up the great work!


  • Thomas

    ThomasThomas

    Author Reply

    When I download the Xcode project I cannot find the “SimpleTable” folder. Mine says RecipeBook. What am I doing wrong?


  • Thomas

    ThomasThomas

    Author Reply

    When I download the Xcode project I cannot find the “SimpleTable” folder. Mine says RecipeBook. What am I doing wrong?


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      Typo. Yes, it should be RecipeBook folder.


  • James

    JamesJames

    Author Reply

    This is what I’ve been looking for thanks:)


  • Martin

    MartinMartin

    Author Reply

    Hi, great tut. But, in RecipeDetailViewController.h you should’nt import Recipe.h, just use @class recipe 🙂 Looking forward to see more tutorials 🙂 Thanks


  • Thomas

    ThomasThomas

    Author Reply

    I can’t get this tutorial to work. I haven’t had any problems with any others but this one is not working. Seems like there are a few steps that you forgot to add? I am following this word for word and with no luck. Are you sure this is all correct?


  • Kmo

    KmoKmo

    Author Reply

    Great tutorial however, the build receives a SIGABRT error after compiling. Using Xcode 4.4.1 (4F1003).
    First I went through the tutorial hand jamming the code in myself and after he build the SIGABRT popped up. Then I started again and just copy and pasted the code directly, same SIGABRT:

    2012-08-18 15:31:01.532 RecipeBook[2859:f803] -[__NSCFConstantString
    name]: unrecognized selector sent to instance 0xa290
    2012-08-18 15:31:01.535 RecipeBook[2859:f803] *** Terminating app due
    to uncaught exception ‘NSInvalidArgumentException’, reason:
    ‘-[__NSCFConstantString name]: unrecognized selector sent to instance
    0xa290’
    *** First throw call stack:
    (0x14b9022 0xeb9cd6 0x14bacbd 0x141fed0 0x141fcb2 0x4630 0xe3a1e
    0xe3d11 0xf58fd 0xf5aef 0xf5dbb 0xf685f 0xf6e06 0xf6a24 0x452de6
    0x4474d0 0xad581 0xad7fa 0x94285d 0x148d936 0x148d3d7 0x13f0790
    0x13efd84 0x13efc9b 0x13a27d8 0x13a288a 0x1c626 0x1d5d 0x1cc5)
    terminate called throwing an exception(lldb)

    At this line:

    cell.textLabel.text = [recipes objectAtIndex:indexPath.row];

    Maybe Xcode doesn’t support this anymore?

    Anyway thanks for the great tutorials, followed a bunch so far with no issues. Excellent explanations.

    -Kmo


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      Could you zip your Xcode project and send it to [email protected]? I’ll take a look.


      • Kmo

        KmoKmo

        Author Reply

        My project turned into a disaster. I believe I found the mistake. I neglected to create the segue as instructed in the initial part of the tutorial. I am going to rebuild the project from the ground up again. Totally my bad. I knew it had something to do with either me or the Xcode build. Like maybe Apple updated Xcode and it deprecated some of the commands. If my new build fails to compile I will zip it up and send it to app coda support.

        By the way the site is great. This is by far the best Xcode tutorial website I have come across. The author(s) definitely do a great job of explaining the underlings of Xcode and why code is the way it is. I’ve learned more doing Appcoda’s tutorials the wrong way, than I have following other tutorials the right way lol. Thank you for putting time and effort into this sight.

        -Kmo


        • Kmo

          KmoKmo

          Author Reply

          I identified the problem and was able to fix it. The recipe array (loaded with recipe1, recipe2, recipe3, ect.) was conflicting with the tableView array that was loading the tableView cells with the names of the recipes located here:

          cell.textLabel.text = [recipe objectAtIndex:indexPath.row];
          The fix was easy but not ideal for working with our recipe objects that were created. The fix is too create a new array and declare it within the recipeViewController.m file and then add the array with the strings attached.
          I.E.
          recipeViewController.m
          @interface minuteMealsViewController ()

          @end

          @implementation minuteMealsViewController {
          NSArray *recipes;
          NSArray *thumbnails;
          NSArray *recipeTitle; //This is my new array.
          }
          @synthesize tableView;
          Then fill the array as so:
          recipeTitle = [NSArray arrayWithObjects:@”Egg Benedict”, @”Mushroom Risotto”, @”Full Breakfast”, @”Hamburger”, @”Ham and Egg Sandwich”, @”Creme Brelee”, @”White Chocolate Donut”, @”Starbucks Coffee”, @”Vegetable Curry”, @”Instant Noodle with Egg”, @”Noodle with BBQ Pork”, @”Japanese Noodle with Pork”, @”Green Tea”, @”Thai Shrimp Cake”, @”Angry Birds Cake”, @”Ham and Cheese Panini”, nil]; //This is my new filled array, I put it right above the //”recipes” array as you can see and right below the “Recipe16” object.

          recipes = [NSArray arrayWithObjects:recipe1, recipe2, recipe3, recipe4, recipe5, recipe6, recipe7, recipe8, recipe9, recipe10, recipe11, recipe12, recipe13, recipe14, recipe15, recipe16, nil];
          Then I changed my:
          cell.textLabel.text = [recipe objectAtIndex:indexPath.row];
          too:
          cell.textLabel.text = [recipeTitle objectAtIndex:indexPath.row];
          Now it works as advertised. However I would rather declare all of my object`s data once in the “.m” file and be able to pull that data when and where I need it. That would be the essence of OOP.
          Next is creating another segue that will lead the user to another view controller that will have the recipe instructions. Will update when I figure that one out. Good Luck.
          -Kmo


          • RMD

            RMDRMD

            Author

            Something a little easier that worked for me.
            Replace this line:
            cell.textLabel.text=[recipes objectAtIndex:indexPath.row];

            with:
            Recipe *thisRecipe=[recipes objectAtIndex:indexPath.row];
            cell.textLabel.text=thisRecipe.name;

            Mine worked after that.


          • Natarajan

            NatarajanNatarajan

            Author

            This worked for me too ..


  • adrian phillips

    i have the same issue as kmo. i built the app according to the tut and it has no warning but app crashes at start due and uncaught exception. here is the reason according to the log: Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[Recipe isEqualToString:]: unrecognized selector sent to instance 0x6e941f0’
    is there anyway you can upload the sample code so we can see where the problem is?


  • PK

    PKPK

    Author Reply

    please give the updated and final running code this is not running and not the proper issue has been given. Kindly update I have followed from start and stucked in here.


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      What’s the error? You can zip your Xcode project and send it to [email protected]. I’ll try my best to help.


      • raghavendra

        hello sir ….. i need to develop an app that sends message another user…… on clicking app icon it should read contacts from address book then on selecting contact no , it sholid go to message composer page where only only send button to send message and a text field to edit message are there. …. is it possible to use xmpp protocol to send regular text messages …… how to merge push tecnology and xmpp protocol services to send regular text messages ……. me using x code 3.2.4 mac osx 10.6.8 ios 4.1….. pls tell me and guide me abot this and step by step development source code


  • adrian phillips

    hi simon,

    i sent you a zip project to the support email and wanted you to take a look at it if you have time. the app crashes at the point cell.textlabel.text. i would appreciate if you could let us know how to fix it.

    adrian


  • JDG

    JDGJDG

    Author Reply

    How could we put the receives in allphabetical order with an index showing down the side?


  • Daragh

    DaraghDaragh

    Author Reply

    Hey Simon, I am having problems and getting the “Use of undeclared identifier ‘recipe’; did you mean ‘Recipe’?” issue on the RecipeDetailViewController.h file. I have followed all your tuts , and have redone this particular tut a number of times. Im sure its a small thing but cant figure it out ;-(


    • Daragh

      DaraghDaragh

      Author Reply

      … Sorry I meant the RecipeDetailViewController.m file. I have enclosed a screen grab of same.


      • Zach Raybould

        Did you manage to fix ?


      • dottorfeelgood

        I have the same issue. Did you find out how to solve it?


      • Nate

        NateNate

        Author Reply

        I FIXED IT (i think)
        You have to @synthesize recipe; in the detailviewcontroller.m
        I just tried it, I dont know if it would compile right though……


  • Zach Raybould

    I get the same error as Daragh (use of undeclared identifier ‘recipe’ ) in RecipeDetailViewController.m


    • Clayton

      ClaytonClayton

      Author Reply

      Did you ever fix this error? this is what i am getting too!


  • Redet Pace

    Redet PaceRedet Pace

    Author Reply

    These tutorials have helped me more than you know! I have a much better understanding of what I’m doing and how it should be done! I would love to see this app continue with using Core Data. Thank you!


  • Clayton Romberg

    This is my error at this point anyone know how to fix?


  • Brendan Sue

    Do you have a final zip file with all the code? I am having trouble after using your initial zip file and following your tutorial exactly. I have the following screenshot to show the only part of the project where there are errors.


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      What are the errors?


      • Brendan Sue

        It says ‘use of undeclared identifier ‘recipe’ in my ‘recipeDetailViewController.m’ for the four instances where the ‘recipe’ is referenced under method ‘viewDidLoad’


        • Jc

          JcJc

          Author Reply

          Try adding self. In front of the recipe


        • Osvaldo Cipriano

          Like Kevin said you must add @synthesize recipe; into RecipeDetailViewController.m


  • kerm

    kermkerm

    Author Reply

    Hi Simon. Please help to fix (use of undeclared identifier ‘recipe’ ) in RecipeDetailViewController.m

    Tried tinkering around but I guess I’m too new for this.

    Very excited to finish this tutorial and make it work. I think it’s something about the xCode version.

    Thanks a lot for helping newbies like me and more power.


    • kevin

      kevinkevin

      Author Reply

      you have to synthesize recipes in recipedetailviewcontroller.m
      @synthesize recipes;


  • Nathan

    NathanNathan

    Author Reply

    Hey Simon, can you give the completed zip file of this project? I (or we) are experiencing a lot of problems like sigabrt errors. Thanks


  • nansaeyuki

    nansaeyukinansaeyuki

    Author Reply

    Hello
    Your lecture has been a great help to me.
    Therefore, in this lecture made​​, an error occurs and the application.
    Mail was sent to you.
    Mail the attached example I made.
    Screen capture of the error I’m going to send an e-mail.
    Thank you.


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      I’ll take a look and reply you soon.


  • Serkan

    SerkanSerkan

    Author Reply

    hey give the running code. because u didnt tell how can we connect images and detail window data from a plist.!!


  • rufus

    rufusrufus

    Author Reply

    someone can tell me how can we load images from a plist array to detailViewController ????? i cant load big images in to detailview.


  • LG

    LGLG

    Author Reply

    Hey Could you send me the finale code folder to see what I’m doing wrong? I’d like to compare so I understand better where my mistake is?

    Thank you!


  • Newbie

    NewbieNewbie

    Author Reply

    I’m trying to implement your ‘Recipe Book’ iPhone app as a learning experience, which has been successful up to the present point where I am unable to instantiate a custom class. My inexperience means I don’t know where to begin to address the problem. Compiler diagnostics show up as follows:

    Code fragment:
    Recipe *recipe1 = [Recipe new];
    recipe1.name = @”Egg Benedict”;

    Produces the error:
    Use of undeclared identifier ‘Recipe’

    Can you help me? Kind regards, Newbie.


    • Vladimir

      VladimirVladimir

      Author Reply

      Import Recipe.h class to RecipeDetailViewController.h file


  • Christopher Harris

    For those getting the following error:

    Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[Recipe isEqualToString:]:

    The issue is in RecipeBookViewController.m. Find the line “cell.textLabel.text = recipe.name;” in – (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }

    The variable recipe is now a NSArray object, in previous tutorials it was an NSString object. Change the code as follows:

    Recipe *recipe = [recipes objectAtIndex:indexPath.row];
    cell.textLabel.text = recipe.name;

    Make sure you include “Recipe.h” in your RecipeBookViewController.h file. Happy coding.


    • Chelsea Richards

      Two thumbs up!!! Thanks for sharing your thoughts it
      helps me a lot to be honest!!! I’m looking forward for any of your updates and
      a post that you might want to share… XOXO:D
      FrameForge3D.com


    • smarterkey

      smarterkeysmarterkey

      Author Reply

      I am a beginner learning to catch up with our programmers and i have just gone through the previous 3 tutorial and now this 1 and just completed this app…I’m amazed it worked 4me…Fantastic g8t tutorial.
      I made the following additions to the tutorial:
      1: Necessary to make the amendment as above regarding “recipe.name”
      2: If you copied the screen shots in tutorial precisely then you should already have included #import “Recipe.h”
      3: In DetailVC.m i had to amend in viewDidLoad from after each “=” to “=self.” followed by “recipe” property as per tutorial
      4 : Also i stupidly forgot to synthesize the “recipe” variable which was added into DetailVC.h on 1 of the screen shots.
      Good luck.


    • Khalid Mehmood Awan

      thanks for the quick help… appreciate it.


    • HLA

      HLAHLA

      Author Reply

      I got same problem but i can soved it easly according your comment. thanks a lot….Christ


    • Yasassri Purnajith

      How to resolve the issue for the search ?


      • Nguyen Duc Hung

        Here is my code for search issue:
        All u need to do is replace SELF with name ( property of Recipe class).
        – (void)filterContentForSearchText:(NSString*)searchText
        {
        NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@”name contains[cd] %@”, searchText];
        searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
        }


        • Le Phuoc Dai

          thank you Hung 🙂


        • Shrikanth

          ShrikanthShrikanth

          Author Reply

          Hi, Didn’t get correct result for search even after making necessary changes. May I get complete code for the same


          • Eran Shmilovitz

            Use the following to display correctly the search results in the table view.

            if (tableView == self.searchDisplayController.searchResultsTableView)
            {
            cell.textLabel.text = [[searchResults objectAtIndex:indexPath.row] name];
            } else {
            cell.textLabel.text = [[recipes objectAtIndex:indexPath.row] name];
            }


    • Eran Shmilovitz

      Another way to do this in just one line of code:
      cell.textLabel.text = [[recipes objectAtIndex:indexPath.row] name];


  • waldorfian

    waldorfianwaldorfian

    Author Reply

    I’m getting errors in the RecipeDetailViewController.m viewDidLoad method around the recipe object references. says it doesn’t recognize it. I don’t understand why. I have the property statement in the RecipeDetailViewController.h file and it is imported into the implementation file.


  • kelmer

    kelmerkelmer

    Author Reply

    Hi, great tutorials. I followed the tutorials right up to this one, but I am having trouble now, no matter what element I click on the list I always end up with the detail view for the first item on the list. I used your code word for word, the only difference is that instead of using the RecipeBookMainController for the TableList I used a separate RecipeListViewController, you think this might be the problem?


    • kelmer

      kelmerkelmer

      Author Reply

      My bad, I forgot to link tableView property with the actual tableview in storyboard!


  • Christian

    ChristianChristian

    Author Reply

    I have been following this tutorial since the first one. I am having trouble with this when i populate the recipe data in the RecipeBookViewController.m file. it gives me an error message where ever there is a “recipe1” on the array. It says use of undeclared identifier “recipe1”. I am new to coding so i am unsure what this means. I know I entered everything in correctly and i imported the Recipe class, i think i might be missing something. Please help.


    • Vladimir

      VladimirVladimir

      Author Reply

      Import Recipe.h class to RecipeDetailViewController.h file


  • Mark Thien

    Mark ThienMark Thien

    Author Reply

    Hi Samuel,

    Would you mind enhance this guide on table view with multiple sub categories? For example like the attached image.


  • bug

    bugbug

    Author Reply

    great tuto, keep going! like this site!


  • creem

    creemcreem

    Author Reply

    After insert the new property into the “recipes” array the project show me some errors:
    “use of undeclared identifier ‘recipe’; did you mean recipes?” or “property name not found…” someone please can tell me why?


    • Vladimir

      VladimirVladimir

      Author Reply

      Import Recipe.h class to RecipeDetailViewController.h file.


      • Daryl Breunissen

        I got the same error but how do you import Recipe.h class to RecipeDetailViewController.h file??


      • Nick

        NickNick

        Author Reply

        Great tutorials thus far! Learned a lot! But now I’m stuck with the error above.

        I get this same error. I tried your suggestion, but it doesn’t work. I’ve followed the OOP tutorial and got the same issue there. Importing the Recipe.h class to RecipeDetailViewController.h file is like -> #import “Recipe.h”

        I also have the “Use of undeclared identifier ‘recipe1″” error.

        When I import the Recipe.h class into the RecipeDetailViewController.h file, the error changes into “Unknown receiver “Recipe”.

        Any help is really appreciated!


        • Nick

          NickNick

          Author Reply

          Fixed it. I had a typo in the Recipe Class filename…


    • Naeem

      NaeemNaeem

      Author Reply

      Write Down “@synthesize recipe;” in RecipeDetailViewController.m


  • ICT student

    Hi

    I tried many times to implemented in my project that I have done by following each word in the document , when i build the app it does not show what I looking for, it does not display and details. Could you help me please to find the solution for it. I will send it to by email


  • ICT student

    Hi, I tried many times ti implemented on my project, I follow the steps and still does not display the details of the pizza, could you please help me to find the solution for it. I send it the file to you by email.


  • punur

    punurpunur

    Author Reply

    Thank you very much, excellent tutorial, and I had some issues , but after going thru the comments I have figured out. Thanks to everyone.


  • John Morris

    this tutorial does not work! I see many people describing the problem with the recipe class reference but the solutions offered do not correct the error. I tried adding a @class reference that didn’t resolve the errors. I tried a @synthesize statement and that resolved the errors but when I ran it, it crashed. I go this error:

    Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[Recipe isEqualToString:]: unrecognized selector sent to instance 0x7505880’

    It really pisses me off that I wasted my time with this tutorial!


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      To fix the error, please change the following line in the “cellForRowAtIndexPath:” method of “RecipeBookViewController.m”

      from:

      cell.textLabel.text = [recipes objectAtIndex:indexPath.row];

      to:

      Recipe *recipe = [recipes objectAtIndex:indexPath.row];
      cell.textLabel.text = recipe.name;

      “recipes” is an array of Recipe object. You should first grab a
      particular Recipe object and retrieve the “name” property to display
      the recipe name in the table.


  • Jonathan Carnie

    Apart from having to add a few self. ‘s to the recipe and modifying the cell.textLabel.text bit, the tut works perfectly. Thanks.


  • James

    JamesJames

    Author Reply

    3 days sitting, but figured out, and now working, thank you)


  • Osvaldo Cipriano

    Hi,

    Great tutorial.
    Is it possible to load the ingredients instead like this with an html? So recipe 1 load an html, recipe 2 another html?


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      Yes, you can change the detail view to a web view. When recipe 1 is selected, you pass the name of the html to the detail view and load the html page in the web view.


  • Hugh Jeremy

    Thanks for the tutorials, with this tutorial, whenever I press a cell to make it show the detailed view, it won’t go to it. It just highlights the cell I pressed. Help much appreciated 🙂


  • Hugh Jeremy

    Hi there, I have a problem I really can’t seem to solve. I am trying to do two things, http://104.131.120.244/customize-table-view-cells-for-uitableview/ to customise the cell design and the content of a more detailed view such as this tutorial offers. I cant seem to get either to work and either have errors or get a SIGABRT error. I have a copy of my code on dropbox and I would really really appreciate it if you could fix my project and tell me where I went wrong (by email or any other way you prefer), I’m only 15 so simple instructions much appreciated. DropBox link: https://www.dropbox.com/sh/wss57sf88vk6u2m/AduYP5drpJ .Thanks very much for all your tutorials. Hugh


  • Patrice Mallette

    Thank you Simon for all your work! I agree with most comments here that it’s one of the best series of tutorials around.

    I also want to say to all the people learning Xcode that after reading all the comments and fixing the few typos, yes, the RecipeBook app is working. You too can figure it out!


  • Jubee

    JubeeJubee

    Author Reply

    can not run


  • Jubee

    JubeeJubee

    Author Reply

    i completed with no issues but when i run the app show this line of code


  • Jay Kingster Akasuki

    Great tutorial easy to fallow.But i have some problem that i can not solve by myself please any body tell me. How to add search bar like previous tutorial to this project.Especially in the section of viewDidload and prepareForSegue method of the RecipeDetailViewController.m


  • Mikhail Dieterle

    I follow this tutorial but result is differ from designed. What I do wrong?


    • Juan Marti

      Juan MartiJuan Marti

      Author Reply

      in the story board, in the botton you will see like a circle with a rectangle inside. Press that, after you press it fix the interface position and it will look good.


  • Arkantos

    ArkantosArkantos

    Author Reply

    Hello thanks for the tutorial, I wanted to ask how can I insert an information here. Plist file, I have to keep the class Recipe.NSObject or I have to change the plist?


  • Stefano Dicati

    Hi, how i can put in project a search bar?


  • Stefan

    StefanStefan

    Author Reply

    Hi guys!

    I’m might a little late, but i started this tutorial yesterday, and I got a problem. I followed all of the previous tutorials, but when i get to RecipeDetailViewController.m, i get the problem that it won’t recognize recipe. I read the comments, so i added the line @synthesize recipe; and now it runs. unfortunately the app breaks when I touch any of the recipes, and gives me the line:
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([RecipeBookAppDelegate class]));

    Can anybody help me?

    Beforehand thanks 🙂


  • Sidney

    SidneySidney

    Author Reply

    I’m having the same problem I see others have had – recipe was not declared so I did what some of the posts said (synthesize recipe). The undeclared went a way but the app crashed. By the way, these are some of the best tutorials i’ve ever seen. This is the first time I was not able to figure out what was wrong. My name is Sidney. I tried to sign up but I couldn’t get past typing in the the capchatka characters.


  • INdraRosli

    INdraRosliINdraRosli

    Author Reply

    Hello guys,

    Please help me on this error..


  • indraRosli

    indraRosliindraRosli

    Author Reply

    Hello Guys,

    Please help me up on this error.Tq


  • Leo

    LeoLeo

    Author Reply

    2 words!
    Love ya!


  • paullauyc@gmail.com

    I am using xCode 4.61. My problem is in prepareForSegue(RecipeBookViewController). The NSArray ingredients object always got a nil value. But i added the debug code in cellForRowAtIndexPath. This is normal.

    Can anybody help me?


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      I’m not sure how you initialize the array. I have just uploaded the source code of the project. Please download it as a reference. This may help to resolve the error.


      • paullauyc

        paullauycpaullauyc

        Author Reply

        Thanks for your sample coding and solved my error.

        My problem in Recipe.h as below:

        //**INCORRECT**

        @property (nonatomic, weak) NSArray *ingredients; // <- "weak"

        //^^CORRECT^^

        @property (nonatomic, strong) NSArray *ingredients;


  • Alyssa DeChiaro

    How would you do something like this for data that is coming from somewhere else (local server) and not hard coded?


  • amp

    ampamp

    Author Reply

    hi simon

    how would you change the cell for row at index path and the segue if you are to change the data source to plist instead of hard coding it in the view did load. lets say i wanted to add the detail view you just created to the plist tutorial you have on your this site. how would i go about that.?

    amp


  • iamxyt

    iamxytiamxyt

    Author Reply

    Can not download the image package


  • Art

    ArtArt

    Author Reply

    Thanks to Simon for the tutorial, and Christopher for solving the NSInvalidArgumentException issue.
    But does anybody know how to solve the NSInvalidArgumentException issue at the location as per below:
    searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];

    Thanks


  • surendra kachhwaha

    instead of default UITableViewCell i used custom UITableViewCell which u made in Tutorial #4 then it is not going to detail page when i click on any cell in the table view. Can u tell me how to make connection between custom cell and detail view controller, thanks


  • Mark

    MarkMark

    Author Reply

    Any reason why

    self.title = recipe.name;

    in RecipeDetailViewController.m has the following error:

    Property ‘name’ not found on object of type ‘recipe’?


  • Daniel Encinas

    Hi. It’s my first comment.
    I need to know if there a easy way to load in this custom table data from a webservice like PARSE.
    I needed to make it run my app and actualize it on the road with new info.
    But all the tuts that I follow, are versy confuse or only works with a simple view.

    Thanks


  • Carl

    CarlCarl

    Author Reply

    Hello, does anyone know how to implement a favorite function with this example ?


  • Osvaldo Cipriano

    If i want to show where the people can eat the dish in another view with map anotation what should i do?


  • Danevas

    DanevasDanevas

    Author Reply

    Hello, I am wondering if someone can share a completed project with me that I can compare to. I am trying to add this detail view to my existing app from the previous tutorial that has a search feature in it. However I have been stuck for what seems like forever and would love to see a working example. Does anyone have a project that has both the detail view and the search working that could post a zip of the Xcode project? Thank you


  • EML

    EMLEML

    Author Reply

    Why not use tableView didSelectRowAtIndexPath: instead ?


  • CEMSOFT SOFTWARE

    just go on , very good tutorials.


  • Graham

    GrahamGraham

    Author Reply

    Hey. Just trying to work with this and noticed it doesn’t work properly now on ios7 changes (navigation bar goes across the image and things are aligned incorrectly). Is there an easy fix for this? Thanks!


  • Ioannis Gman

    hello.im wondering..in detail view how can we share image and label in Facebook or twitter??
    that would be very handy


  • Adrienne Henry

    Hi! first off.. thanks for the tutorial! I was wondering though.. is there a way to make a second, third and so on detail view controller?


  • Roger

    RogerRoger

    Author Reply

    @simonng:disqus hello , I can not get to work the image in the Detail View Controller, I have my images in a array ? I could pass everything else expect the image.

    Thank you


  • Joanne

    JoanneJoanne

    Author Reply

    I followed your code logic and recipe no issues on the build. However when I click on the recipe it’s moved to the recipe detail page but there’s not image or ingredient text. I see the “CUICatalog: Invalid asset name supplied: (null), or invalid scale factor: 2.000000
    in the debug window but I can not see where the error is originating from.

    Great tutorial for a first time app developer


  • Salar N (Dr Bongo)

    Bless YOU! Thank You! and after a long, unnecessary, struggle with a break in the code, I realized the answer was a scroll down to the comments! Thank you Coda team and indeed Mr. Simon NG for this beautifully crafted tutorial! I ran through it, 7 times, and 13 hours later, I don’t have a recipe app, no doubt a customized app i was looking to build. Thank you and please don’t stop these tutorials. Even though i am an avid, and somewhat trained programmer, getting to as the authors call a “writers block” is cured by these tutorials. Back to basics! Thank YOU AppCode team. Is there a place where you accept donations perchance? I’d like to gift to show my support to the team.


  • gaganglobin76

    Hi, Very good tutorial about UICollection view, TableView, PageView. I have some ideas to improve this app with database support. Can you please tell me how to store this Recipes contents to SQLite database ?


  • Prerna Mathur

    Hi I tried the following

    static NSString *simpleTableIdentifier = @”SimpleTableCell”;

    SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@”SimpleTableCell” owner:self options:nil];

    cell = [nib objectAtIndex:0];

    }

    Recipe *recipe = [myRecipes objectAtIndex:indexPath.row];

    UILabel *nameLabel = (UILabel *)[cell viewWithTag:101];

    nameLabel.text = recipe.name;

    UIImageView *thumbnailmage = (UIImageView *)[cell viewWithTag:100];

    thumbnailmage = recipe.imageFile;

    The above doesnt print anything on the table cell but when I print the log it does give me the list of recipes. I created a custom Nib file as in the other tutorials with the cell identifier SimpleTableCell and tags as 101, 100


  • Kenny

    KennyKenny

    Author Reply

    Thanks for sharing this! Any idea what could be wrong with my code even though I think I am following it step by step correctly 🙁
    Following is the output, hopefully you can help me to identify the problem.

    2014-06-11 22:38:11.134 RecipeBook[12666:60b] Cannot find executable for CFBundle 0x1092390a0 (not loaded)

    2014-06-11 22:38:11.193 RecipeBook[12666:60b] -[Recipe copyWithZone:]: unrecognized selector sent to instance 0x10953d170

    2014-06-11 22:38:11.197 RecipeBook[12666:60b] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[Recipe copyWithZone:]: unrecognized selector sent to instance 0x10953d170’

    *** First throw call stack:

    (

    0 CoreFoundation 0x0000000101951495 __exceptionPreprocess + 165

    1 libobjc.A.dylib 0x00000001016b099e objc_exception_throw + 43

    2 CoreFoundation 0x00000001019e265d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205

    3 CoreFoundation 0x0000000101942d8d ___forwarding___ + 973

    4 CoreFoundation 0x0000000101942938 _CF_forwarding_prep_0 + 120

    5 UIKit 0x00000001003dcee0 -[UILabel _setText:] + 126

    6 RecipeBook 0x000000010000389d -[RecipeBookViewController tableView:cellForRowAtIndexPath:] + 333

    7 UIKit 0x0000000100331f8a -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 348

    8 UIKit 0x0000000100317d5b -[UITableView _updateVisibleCellsNow:] + 2337

    9 UIKit 0x0000000100329721 -[UITableView layoutSubviews] + 207

    10 UIKit 0x00000001002bd993 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 354

    11 QuartzCore 0x0000000103f3b802 -[CALayer layoutSublayers] + 151

    12 QuartzCore 0x0000000103f30369 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 363

    13 UIKit 0x00000001002b1f70 -[UIView(Hierarchy) layoutBelowIfNeeded] + 521

    14 UIKit 0x00000001003747d6 -[UINavigationController _layoutViewController:] + 1077

    15 UIKit 0x00000001003720b4 -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] + 395

    16 UIKit 0x00000001002a268e -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 235

    17 UIKit 0x00000001002a1184 +[UIViewAnimationState popAnimationState] + 281

    18 UIKit 0x0000000100538f7a -[UINavigationTransitionView transition:fromView:toView:] + 2504

    19 UIKit 0x00000001005385b0 -[UINavigationTransitionView transition:toView:] + 25

    20 UIKit 0x00000001003754d7 -[UINavigationController _startTransition:fromViewController:toViewController:] + 2893

    21 UIKit 0x0000000100375787 -[UINavigationController _startDeferredTransitionIfNeeded:] + 547

    22 UIKit 0x0000000100376238 -[UINavigationController __viewWillLayoutSubviews] + 43

    23 UIKit 0x0000000100490895 -[UILayoutContainerView layoutSubviews] + 202

    24 UIKit 0x000000011039d040 -[UILayoutContainerViewAccessibility(SafeCategory) layoutSubviews] + 43

    25 UIKit 0x00000001002bd993 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 354

    26 QuartzCore 0x0000000103f3b802 -[CALayer layoutSublayers] + 151

    27 QuartzCore 0x0000000103f30369 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 363

    28 QuartzCore 0x0000000103f3b736 -[CALayer layoutIfNeeded] + 162

    29 UIKit 0x0000000100363a22 -[UIViewController window:setupWithInterfaceOrientation:] + 264

    30 UIKit 0x000000010029acad -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 4360

    31 UIKit 0x0000000100299b9f -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 36

    32 UIKit 0x0000000100299aef -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 101

    33 UIKit 0x0000000100298dfe -[UIWindow _updateToInterfaceOrientation:duration:force:] + 377

    34 UIKit 0x000000010035770a -[UIViewController _tryBecomeRootViewControllerInWindow:] + 147

    35 UIKit 0x0000000100293b1b -[UIWindow addRootViewControllerViewIfPossible] + 490

    36 UIKit 0x0000000100293c70 -[UIWindow _setHidden:forced:] + 282

    37 UIKit 0x000000011037ed73 -[UIWindowAccessibility(SafeCategory) _orderFrontWithoutMakingKey] + 68

    38 UIKit 0x000000010029cffa -[UIWindow makeKeyAndVisible] + 51

    39 UIKit 0x0000000100258c98 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1788

    40 UIKit 0x000000010025ca0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660

    41 UIKit 0x000000010026dd4c -[UIApplication handleEvent:withNewEvent:] + 3189

    42 UIKit 0x000000010026e216 -[UIApplication sendEvent:] + 79

    43 UIKit 0x000000010025e086 _UIApplicationHandleEvent + 578

    44 GraphicsServices 0x0000000103aca71a _PurpleEventCallback + 762

    45 GraphicsServices 0x0000000103aca1e1 PurpleEventCallback + 35

    46 CoreFoundation 0x00000001018d3679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41

    47 CoreFoundation 0x00000001018d344e __CFRunLoopDoSource1 + 478

    48 CoreFoundation 0x00000001018fc903 __CFRunLoopRun + 1939

    49 CoreFoundation 0x00000001018fbd83 CFRunLoopRunSpecific + 467

    50 UIKit 0x000000010025c2e1 -[UIApplication _run] + 609

    51 UIKit 0x000000010025de33 UIApplicationMain + 1010

    52 RecipeBook 0x0000000100004a43 main + 115

    53 libdyld.dylib 0x0000000101fe95fd start + 1

    )

    libc++abi.dylib: terminating with uncaught exception of type NSException


    • Kenny

      KennyKenny

      Author Reply

      I got the app working now after I keep debugging .. Here is the answer .

      Recipe *recipe = [recipes objectAtIndex:indexPath.row];
      cell.textLabel.text = recipe.name;


  • James Tighe

    Hi,

    So far I am finding your tutorials really good. They are helping me understand the iOS basics and get started programming.

    I am having a slight issue however. I am trying to get the RecipeDetailViewController to display the ingredients in a tableView rather than textView.

    I am probably approaching this completely wrong but heres what I tried.

    RecipeDetailViewController.m

    I added the tableView to the storyboard and created the prototype cell with its own identifier.

    I am stuck at how to populate the tableView. Could anyone assist on the coding for the UITableView in RecipeDetailViewController.m?

    I just want to pass the recipe.ingredients property from the RecipeViewController to the RecipeDetailViewController into a tableView.

    Would I simply use

    – (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    static NSString *CellIdentifier = @”CustomTableCell”;
    RecipeTableCell *cell = (RecipeTableCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell…
    if (cell == nil) {
    cell = [[RecipeTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Display recipe in the table cell
    Recipe *recipe = [recipes objectAtIndex:indexPath.row];
    cell.ingredientLabel.text = self.recipe.ingredients;

    return cell;
    }

    Cheers

    James


  • Czarek

    CzarekCzarek

    Author Reply

    App, runs but I get empty image view and emptyingredients list, anyone knows, what may be the reason?


  • Czarek

    CzarekCzarek

    Author Reply

    App runs, but I’m getting empty image and empty ingredients list. I have already checked the connections in storyboard and it seems ok (its like in this tutorial). Anyone have an idea what may be the cause?


  • AppNovice

    AppNoviceAppNovice

    Author Reply

    HELP, I have completed the app and have changed the required coding, my app runs however it doesn’t display the recipe images, prep time or ingredients in the simulation. However, I have linked the images, prep time and ingredients as stated in the tutorial. Many Thanks


  • Satheeshkumar Naidu

    Please add Plist and sqli and web services


Leave a Reply to John Morris
Cancel Reply

Shares