iPhone Programming Tutorial - Populating UITableView With An NSArray
The goal of this tutorial is to show you how to populate a UITableView with data from an array of objects. This will be the building block to display XML data as well as SQL data.
The theme of this application will be fruit. We will create an array of “fruit” objects that have some additional information besides the name. We will populate a UITableView with the names of the fruits. When the user selects a fruit from the list, the view will transition to another one and display specific details about that fruit.
I will try to be as detailed as possible however it would be useful if you have completed the following tutorials as I will use concepts from each of them:
- Create a Navigation-Based Application
- Create a New Fruit Class Object
- Create and Populate an NSArray
- Add a New View To Your Project
- Connect The View To Code
- Populate A UITableView With Object Data
- Transition To New Views And Show Data Based On The Row Selected
We are going to create our “fruit” objects that will be used in the application. If you are not too familiar with object oriented programming…Google it. That tutorial would be a little too huge for me to write.
Click on File -> New File… The object we are creating will inherit from NSObject, so select NSObject Subclass and click Next.
The next screen will ask you to name it. Go ahead and name it “Fruit” and make sure that “Also create Fruit.h” is checked. It should look like the screen below. Then, click Finish.
Now, we are going to define the properties of a “Fruit” object. For this application a fruit will have a name and a description. Open Fruit.h and add the following code:
We have created the properties needed to represent our fruit. There is one line that you may be unfamiliar with. The line -(id)initWithName:(NSString*)n description:(NSString *)desc; is a definition for a function. This function will be called to initialize a Fruit object. All NSObjects have an init method, but we want to create our own so that we can pass in a name and description when the object is created.
Open up Fruit.m and add the following code:
Here we implement the initWithName method. The code here seems pretty straight forward. We are basically setting our local copies of name and description to the arguments passed to this method. The important thing to notice here is the return self line. This is crucial for using this method as a constructor. It allows this function to return the newly created instance of a fruit object.
Next, we are going to create an array of fruit objects. Open up FruitAppDelegate.h and add the following code:
All we are really adding here is an NSMutableArray property. I used NSMutableArray instead of NSArray because it has a few more methods making it more flexible.
Now, open up FruitAppDelegate.m and add @synthesize fruits to the top. This is so other objects will have access to the fruits array. Also, be sure to include the import statement for Fruit.h.
Now add the following code to the applicationDidFinishLaunching method.
What we are doing here in the 1st three lines is creating new instances of a fruit object. Notice that instead of calling init, we are calling the initWithName method that we created. This is allowing us to pass in a name and a description to each of the fruits.
The next line [self.fruits = [[NSMutableArray alloc] initWithObjects:apple,orange,watermelon,nil]; builds a new array from the objects we just created. It is important to pass in nil as the last argument in an NSMutableArray. It will not work unless you remember this.
Now we are going to create the view that will be displayed when the user selects a fruit. Double click on any one of your .xib files to open up Interface Builder.
Click File -> New and select view and click choose.
You should now see the new view (it will be blank) and the objects associated with it. We need some sort of text field to display the description of the fruit. For this tutorial I have chosen a UITextView as opposed to a UITextField. This is because a UITextView is multi-line and is great for displaying more than one line of text. So, go ahead and drag it on to your view. Your view window should now look like this:
Now click File -> Save. One important thing to keep in mind is to make sure you are saving it in the current project’s directory. It seems that every time I add a view to a project, the default directory is not my project’s directory. Name this file FruitViewController and click Save.
Another window should show up after you click save. It is asking you if you want to add this view to your project. Just check the box net to Fruit ,click Add, and close Interface Builder.
Close Interface Builder and go back to X-Code.
We need to create a ViewController to handle our View. Click File -> New File… Select UIViewController subclass and click Next.
Name this file FruitViewController.m and check the box that says “Also create “FruitViewController.h” . Click Finish.
Now we will declare an Interface Builder Outlet for the UITextView that we added to the view. Open up FruitViewController.h and add the following code.
This line allows us to associate the fruitDescription property with the UITextView we created. Open up FruitViewController.m and add this code underneath @implementation keyword. This creates default “getter” and “setter” methods for the fruitDescription property.
Double click on FruitViewController.xib to open it in interface builder. We need to connect the view to the FruitViewController class we just created. Click on the File’s Owner object.
Click Tools -> Identity Inspector. Select FruitViewController from the dropdown next to class. Notice that under the Class Outlets section you will see the UITextView property we created.
The last step in interface builder is to connect the UITextView. Click Tools -> Connection Inspector. You should see an Outlet that says fruitDescription. Click in the corresponding circle and drag it over the UITextView on your view and release it.
Now, click the circle next the word View under outlets and drag it to the View object inside of the window that says FruitViewController in the title. When you are done the screen should look like this:
Now close Interface Builder.
The first thing we are going to do here is create a property for our new view so that it can be transitioned to when a fruit gets clicked on. Open RootViewController.h and add the following code:
We are just creating a property for the fruitViewController that we added to the project. Also note that I added the #import “FruitViewController.h” line. this will allow us to create new instances of the FruitViewController object.
Now open the RootViewController.m and find the numberOfRowsInSection method. This method tells the UITableView how many rows it will be displaying. In our case it will be the size of the array of fruits. Add the following code (click the image to enlarge):
The first line allows us to gain access to the appDelegate of our application. This is where we defined the fruit array. Once we have access to the delegate the count property of the fruit gets returned.
Now find the cellForRowAtIndexPath method and add the following code:
So the first line we added is the “FruitAppDelegate *appDelegate…” line. Again, this is giving us access to the appDelegate object where we declared the fruit array. The next line calls the objectAtIndex method on the Array of fruits. The index we will be using can be accessed via indexPath.row. This is an integer value representing each row of the UITableView. Finally, we call the setText method of the cell, to display the name of the fruit in each cell at the given index.
This is the last step. We are going to detect which row in the UITableView the user selected. Find the method called didSelectRow and add the following code(click image to enlarge).
This method gets called every time a user taps on a cell in the UITableView. The parameter indexPath has a property called row that is the integer value of the cell the user clicked on. To access this, we call indexPath.row.
The first line again gives us access to the appDelegate. The next line indexes into the fruits array and makes a copy of the selected fruit object.
The next section starting with “if(self.fruitView == nil)”, initializes the viewController if it hasn’t already been initialized (see my previous tutorial if you need more of an explanation on this). One thing to take note of: Make sure that the parameter you pass to initWithNibName matches the name of the .xib file you used for your view. So in our case, its FruitViewController.
Following this line is the line that pushes the viewController on to the navigationController stack. This causes the view to transition to the new view.
The last 2 lines pass the fruit information to the new view. They are fairly self explanitory. We first set the title of the view to the name of the fruit and then set the description text to the description of the fruit.
Now click Build and Go and your app should launch. Here are some screenshots of how it should look.
And after clicking on a fruit…
Well, I hope that you got a lot out of this tutorial. As always, if you have any questions or comments, feel free to leave them in the comments section of this post. We also have a forum to help you will all of you iphone related questions. If you get lost, you can download the sample code here
Happy iCoding!
- Posted on 8 Aug 2008 in Interface Builder, iPhone Programming Tutorials
- Digg |
- Del.icio.us |
- Stumble |
125 Responses
Sebastien Says:
August 8th, 2008 at 10:19 pm
another nice Tutorial. I’m very newbie in Iphone Dev and Objective-C. I’ve read the “Objective-C programming” at the apple Dev Center but I need alot of source code to understand so I can’t wait for the next tutorial!
I have some problems to understand when and how to use “@property” (retain,copy, etc). The next thing i need to practice is the connections in the Interface Builder.
Thank you for your great tutorials!
bobcubsfan Says:
August 9th, 2008 at 2:12 pm
Great tutorial! Thanks. What I am learning among other things is how picky coding is in regard to punctuation and capitalization. Very easy to make mistakes and generate errors.
stowns Says:
August 9th, 2008 at 6:25 pm
honestly…you’re the shit. I have zero experience with C and had no clue where to start. Your tutorials have seriously sped things up. Thanks for taking the time to spread the knowledge
iphoner Says:
August 10th, 2008 at 5:28 am
another great one. thankyou. It would be really good to see some tutorials on creating a musical instrument. Apple did have source code for a ‘Kalimba’ instrument on their dev site but this has since been taken down.
Phil Says:
August 10th, 2008 at 8:50 am
Thanks Brandon, another great tutorial - would it be possible for you to do a tutorial that focuses on the UIScrollView using the mulitouch to zoom in / out images etc?
stowns Says:
August 10th, 2008 at 6:05 pm
one thing i would love to see added to this tutorial is a summary paragraph at the end. Something that sums up how all the files interact upon execution. But only because i’m a nub
Leo Says:
August 11th, 2008 at 2:23 am
First of all: thanks for this great series of tutorials. They’re very helpful for me!
One question regarding the “cellForRowAtIndexPath” function in this tutorial:
FruitAppDelegate *appDelegate = (FruitAppDelegate *)[[UIApplication sharedApplication] delegate];
Fruit *f = (Fruit *)[appDelegate.fruits objectAtIndex:indexPath.row];
[cell setText:f.name];
[f release];
I understand why you release the “f” object. But I don’t understand why you don’t do the same with the “appDelegate” object. Shouldn’t that object be released from memory as well? Or is it somehow being released in a different way, by a different function? Thanks for any insight you can provide! ![]()
Brandon Says:
August 11th, 2008 at 9:39 am
The reason the appDelegate object does not get released is because we are not building a new instance of it. All we are doing is getting a reference to it. If you release it, you will be releasing your application’s appDelegate.
I hope that helps.
bobcubsfan Says:
August 11th, 2008 at 5:11 pm
Brandon, I used the tutorial as a model to build an app, and ran into a problem.
When the array items exceed what the screen can show, and I “scroll” up, the program locks up.
I extended your array, and got the same results.
Any ideas?
Brandon Says:
August 12th, 2008 at 12:16 pm
Hrmm… That is odd. I’ll try to mess with it when I get some time. In the mean time, if you figure it out let me know.
thanks
bobcubsfan Says:
August 12th, 2008 at 12:53 pm
this is the change I made to your code that causes the problem.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
Fruit *apple = [[Fruit alloc] initWithName:@”Apple” description:@”Red Delicious are my favorite”];
Fruit *orange = [[Fruit alloc] initWithName:@”Orange” description:@”MMM…Fresh squeezed orange juice”];
Fruit *watermelon = [[Fruit alloc] initWithName:@”Watermelon” description:@”My favorite flavor of Jolly Ranchers”];
Fruit *apple2 = [[Fruit alloc] initWithName:@”Apple” description:@”Red Delicious are my favorite”];
Fruit *orange2 = [[Fruit alloc] initWithName:@”Orange” description:@”MMM…Fresh squeezed orange juice”];
Fruit *watermelon2 = [[Fruit alloc] initWithName:@”Watermelon” description:@”My favorite flavor of Jolly Ranchers”];
Fruit *apple3 = [[Fruit alloc] initWithName:@”Apple” description:@”Red Delicious are my favorite”];
Fruit *orange3 = [[Fruit alloc] initWithName:@”Orange” description:@”MMM…Fresh squeezed orange juice”];
Fruit *watermelon3 = [[Fruit alloc] initWithName:@”Watermelon” description:@”My favorite flavor of Jolly Ranchers”];
Fruit *apple4 = [[Fruit alloc] initWithName:@”Apple” description:@”Red Delicious are my favorite”];
Fruit *orange4 = [[Fruit alloc] initWithName:@”Orange” description:@”MMM…Fresh squeezed orange juice”];
Fruit *watermelon4 = [[Fruit alloc] initWithName:@”Watermelon” description:@”My favorite flavor of Jolly Ranchers”];
Fruit *apple5 = [[Fruit alloc] initWithName:@”Apple” description:@”Red Delicious are my favorite”];
Fruit *orange5 = [[Fruit alloc] initWithName:@”Orange” description:@”MMM…Fresh squeezed orange juice”];
Fruit *watermelon5 = [[Fruit alloc] initWithName:@”Watermelon” description:@”My favorite flavor of Jolly Ranchers”];
self.fruits = [[NSMutableArray alloc] initWithObjects:apple,orange,watermelon,apple2,orange2,watermelon2,
apple3,orange3,watermelon3,apple4,orange4,watermelon4,apple5,orange5,watermelon5,nil];
Hanno Says:
August 13th, 2008 at 1:06 am
Thx Brandon for that tutorial.
One question:
what is the difference in accessing an objects properties or methods via foo.property to [foo property]?
BrewersFan Says:
August 13th, 2008 at 11:23 am
Brandon thank you for tutorial.
I am experiencing the same issue bobcubsfan. Both my simulator and hardware lock up when I scroll quickly through list. I don’t have any insight as to why.
Also does anyone know how to access/convert the fruitDescription as a NSString?
Maybe:
NSString *str = fruitDescription.text
bobcubsfan Says:
August 13th, 2008 at 2:36 pm
When running on my iPhone, the program quits after scrolling twice without making a selection.
bobcubsfan Says:
August 13th, 2008 at 3:27 pm
This might be a clue:
The debugger (GDB) was launched when the program bombed.
bobcubsfan Says:
August 13th, 2008 at 6:05 pm
Hey Brewers fan.
I added NSString *mydesc; to
RootViewController.h
@interface RootViewController : UITableViewController {
FruitViewController *fruitView;
NSString *mydesc;
and the second @property …
@property(nonatomic,retain) FruitViewController *fruitView;
@property(nonatomic,retain)NSString *mydesc;
then,
in RootViewController.m after the line in the (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
method
[self.fruitView.fruitDescription setText:[fruit description]];
I added this:
mydesc =[fruit description];
no errors, so I guess it works.
Brandon Says:
August 13th, 2008 at 8:03 pm
Hmmm… I’m still working on the issue of the simulator locking up when scrolling. I have compared my code to numerous examples by Apple and can’t seem to see any significant difference.
Go ahead and post this issue in the forums and see if anyone has a solution.
bobcubsfan Says:
August 13th, 2008 at 10:59 pm
Hey Brewers fan. I forgot this in RootViewController.m
add the @synthesize mydesc; line.
@implementation RootViewController
@synthesize fruitView;
@synthesize mydesc;
BrewersFan Says:
August 14th, 2008 at 7:37 am
Thanks bobcubsfan!!! I appreciated you posting NSString code.
I hope Brandon or message board feedback can resolve the lockup issue.
bobcubsfan Says:
August 14th, 2008 at 7:58 am
Hey Brewersfan, you are welcome. Did it work for you? I am troubleshooting the lockup problem as well.
AstrosFan Says:
August 14th, 2008 at 8:02 am
Hi. I was wondering how would I be able to use this tutorial but at the same time, have a tab bar at the bottom. I already made a tab bar application but it doesn’t have the RootViewController or anything. Should I just go ahead and make one? Or is there another way?
mainstreetmark Says:
August 14th, 2008 at 4:56 pm
Hey dude -
This is exactly the topic and scope I was looking for. I have successfully made a list of stuff.
I eventually hope to write a native app for itunesregistry.com, but I’ve got nearly no experience in Cocoa, so this will be a learning experience…
jonas Says:
August 15th, 2008 at 6:07 am
Thank you for excellent articles! Seems like I will have to go brush off some dust from an Objective C book thats lying around here somewhere — your postings really gave me the inspiration for doing so!
Keep up the great work!
daniel Says:
August 15th, 2008 at 6:12 am
why in “cellForRowAtIndexPath” method of RootViewController.m need add
[f release]
but not need release “fruit” in didSelectRowAtIndexPath
they also have use the same way (also from fruits NSMutableArray) to get the ref.
[Fruit *fruit = (Fruit *)[appDelegate.fruits objecctAtIndex:indexPath.row];
BrewersFan Says:
August 15th, 2008 at 8:25 am
Hey bobcubsfan, I was able to get it to work kinda..
Basically I’m trying to let the user email the description once they have selected the fruit. I have an email button on FruitViewController.xib.
Here is my code:
RootViewController.h
@interface RootViewController : UITableViewController {
FruitViewController *fruitView;
NSString *mydesc;
}
@property(nonatomic,retain) FruitViewController *fruitView;
@property(nonatomic,retain) NSString *mydesc;
@end
RootViewController.m
@implementation RootViewController
@synthesize fruitView;
@synthesize mydesc;
[self.navigationController pushViewController:self.fruitView animated:YES];
self.fruitView.title = [fruit name];
[self.fruitView.fruitDescription setText:[fruit description]];
mydesc =[fruit description];
FruitViewController.h
@interface FruitViewController : UIViewController {
IBOutlet UITextView *fruitDescription;
NSString *mydesc;
}
@property(nonatomic,retain) IBOutlet UITextView *fruitDescription;
@property(nonatomic,retain) NSString *mydesc;
- (IBAction)EmailFruit;
@end
FruitViewController.m
@implementation FruitViewController
@synthesize FruitFruitFruitDescription;
@synthesize mydesc;
-(IBAction)EmailFruit {
NSString *str1 =@”mailto:?&subject=Fruit&body=”;
//NSString *str2 =mydesc;
NSString *SMessage =[NSString stringWithFormat:@"%@%@",str1,mydesc];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:SMessage]];
}
When I run this the text field of the email should read description however I get (Null).
Any idea how to fix???
Thanks again for your HELP…
Brandon Says:
August 15th, 2008 at 9:17 am
I think I have solved it!
After reading the post left by daniel, I decided to investigate my choice for releasing the f object.
After some inspection, I realized that the “f” object wasn’t a new instance of Fruit, but a reference to an existing Fruit object.
Releasing this object, removes the Fruit at that cell from memory and causes the app to crash.
So to fix the crashing problem, remove the
[f release];
line from cellForRowAtIndexPath method inside of RootViewController.m.
Thank you to daniel for bringing this to my attention. I will update the tutorial later today.
bobcubsfan Says:
August 15th, 2008 at 10:54 am
Brandon, you rock! It always seems to be the case that one small thing is the source of a bug!
Brandon Says:
August 15th, 2008 at 12:32 pm
Thanks Bob,
yea it’s always something dumb that you overlook. So I assume this fixed the bug for you then?
bobcubsfan Says:
August 15th, 2008 at 3:47 pm
Indeed it did. When I was looking at the code, I was kind of wondering about the “f release”, but am still too much of a novice to have nailed it down.
BrewersFan Says:
August 16th, 2008 at 7:55 am
Hey I got my code to work bobcubsfan. Thanks again for the post. Brandon thanks for the fix.
This is a GREAT BLOG and you guys have been a big help.
BrewersFan Says:
August 16th, 2008 at 10:44 am
Does anyone have idea on how to add search bar below list to search array? My list in my app is long and search feature would benefit user.
bobcubsfan Says:
August 16th, 2008 at 2:47 pm
Apple has sample code for a table search with an array. If you want, I can e-mail the dmg to you.
bobcubsfan Says:
August 16th, 2008 at 4:24 pm
Brandon,
Once a value has been passed, how is the value stored for use elsewhere?
For example, selecting Apple, yields Red Delicious are my favorite in [self.fruitView.fruitDescription setText:[fruit description]];
So, if I want to use the result, how can I store in and where?
Brandon Says:
August 16th, 2008 at 7:29 pm
@bobcubsfan,
Im not sure I understand your question. Are you asking me how you would store the description of the selected item?
Let me know so that I can further assist you.
bobcubsfan Says:
August 16th, 2008 at 10:37 pm
I am used to languages that have global variables. For example, declaring a global or public string makes it available everyone, while a private variable is available only in the routine, or method where it is declared. So, maybe I want to capture the description and use it somewhere else, perhaps to just use a substring of it.
I am thinking that maybe variables declared in the “delegate” and made available by the code in RootViewController
FruitAppDelegate *appDelegate = (FruitAppDelegate *)[[UIApplication sharedApplication ] delegate];
would do the job.
BrewersFan Says:
August 17th, 2008 at 3:01 pm
Hey bobcubsfan,
in the
RootViewController.m
I changed:
mydesc =[fruit description];
TO:
self.fruitView.mydesc =[fruit description];
This changed (null) to the description…
Also thank you for the offer to email table search with an array from Apple.
I have looked at example, specifically 3_SimpleIndexedTableView.
I would like to add the search functionality to this list however I am just not proficient enough to navigate the code changes..
I was fishing to see if someone with more proficiency might know how. This way I don’t have to pull all of my hair out…
marcus Says:
August 18th, 2008 at 9:32 pm
Should this compile without warngings? I get warnings in the FruitAppDelegate.m on these lines of code
Fruit *apple = [[Fruit alloc] initWithName:@”Apple” description:@”My favorite is green”];
because it says no ‘initwithName:description:’ method found.
Did I miss a step? I’m import “Fruit.h” into the FruitApp Delegate.m. When I build and go I just get a black screen and it goes into debug mode.
Brandon Says:
August 19th, 2008 at 7:05 am
@marcus,
If you are getting this warning, it probably means that you did not declare this method inside of your fruit.h.
- (id) initWithName:(NSString*)n description:(NSString*desc);
Let me know if that solves your problem. You also may have missed the step where you implement this method inside of fruit.m
marcus Says:
August 19th, 2008 at 10:10 am
Thanks for the help Brandon. I did declare it in fruit.h. Here is my fruit.h. Notice iniWithName not initWithName. Ooops. It’s working now. Figured it had to be something simple but obscure.
#import
@interface Fruit : NSObject {
NSString *name;
NSString *description;
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *description;
- (id)iniWithName:(NSString *)n description:(NSString *)desc;
@end
Brandon Says:
August 19th, 2008 at 10:23 am
hehe great to hear you got it working. I hate type-o errors, they take so long to troubleshoot.
Thanks for being a part of this site!
marcus Says:
August 19th, 2008 at 10:45 am
Well, I spoke too soon. It comes up fine and displays the fruits but then when I click on a fruit it crashes. It’s crashing on the line:
self.fruitView.title = [fruit name];
in the did select a row function.
Any ideas?
iPhone Programming Tutorial - Creating a ToDo List Using SQLite Part 1 | iCodeBlog Says:
August 19th, 2008 at 11:46 am
[...] while still explaining the new stuff in detail. I will assume that you have completed the fruits tutorial and it’s [...]
bobcubsfan Says:
August 19th, 2008 at 12:11 pm
Marcus
Try commenting the line with the error.
//self.fruitView.title = [fruit name];
See if the error “drifts”.
Brandon Says:
August 19th, 2008 at 12:38 pm
@Marcus,
You can open up the error terminal while your application is running. It will give you a detailed log of the error. This should give you some insight as to why your app crashed.
You can access it by clicking the GDB icon inside of XCode (its located on the middle toolbar and looks like a terminal screen) after clicking Build and Go.
Paste the error output in the comments so we can see what the problem is.
marcus Says:
August 19th, 2008 at 4:54 pm
Here is the gdb output. Thanks again for your help.
[Session started at 2008-08-19 16:53:59 -0700.]
2008-08-19 16:54:02.463 Fruit[4359:20b] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil’
2008-08-19 16:54:02.465 Fruit[4359:20b] Stack: (
2530500939,
2517487867,
2530500395,
2530500458,
2422354896,
2421430788,
2421430548,
816674028,
816673653,
8806,
816434578,
816463537,
816274443,
816209415,
816206378,
829003042,
829012108,
2530002453,
2530004216,
829005112,
829005309,
816175835,
816221412
)
[Session started at 2008-08-19 16:54:02 -0700.]
Loading program into debugger…
GNU gdb 6.3.50-20050815 (Apple version gdb-960) (Sun May 18 18:38:33 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i386-apple-darwin”.warning: Unable to read symbols for “/System/Library/Frameworks/UIKit.framework/UIKit” (file not found).
warning: Unable to read symbols from “UIKit” (not yet mapped into memory).
warning: Unable to read symbols for “/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics” (file not found).
warning: Unable to read symbols from “CoreGraphics” (not yet mapped into memory).
Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/not_too_shabby/Library/Application Support/iPhone Simulator/User/Applications/6B90C11F-BA39-4AF0-A7B0-8F8495CE80BE/Fruit.app/Fruit’, process 4359.
(gdb)
Brandon Says:
August 19th, 2008 at 7:36 pm
Hrmm… That is strange. It’s so hard to troubleshoot without seeing your code. I will post up the sample code for this tutorial and you can compare it to yours.
BrewersFan Says:
August 21st, 2008 at 7:37 am
Hey bobcubsfan, Brandon,
I am trying to add search feature to array. Specifically I am attempting to add functionality from 3_SimpleIndexedTableView Apple example with side letter search. Basically my code is generating a bunch of errors.
I ‘m wondering if there is a better approach? Bobcubsfan you mentioned Apple has sample code for a table search with an array. Which the one are you’re referring to?
At the end of the day I am looking for a cleaner easier way to add search to this app. It doesn’t have to be side list. I would actually prefer search bar. Do you know of example of this? Can you send my way?
Any help with respect to this is appreciated.
BrewersFan
bobcubsfan Says:
August 21st, 2008 at 7:47 am
Assuming you have access to Apple Dev, here is the link
If not, give me your e-mail and I will send you the DMG for TableSearch
Chris McIntosh Says:
August 21st, 2008 at 10:30 am
I am having an issue with transitioning from the main view to the second view, it errors out giving this: -[RootViewController taskViewC]: unrecognized selector sent to instance 0×44f8b0′
I am actually extending the sqlLite app, but figure this would be a good spot to start as this is where the transitioning code i based it on was from.
BrewersFan Says:
August 21st, 2008 at 10:32 am
Thank bobcubsfan,
for some reason I did not see TableSearch Code last time I look in Dev Center Site.
I will give it a try and let you know.
thanks again…
Chris McIntosh Says:
August 21st, 2008 at 10:39 am
okay, fixed it. I forgot to add a synthesize line in for my view.
Chris McIntosh Says:
August 21st, 2008 at 1:46 pm
Question about libraries. Cant get into the forum because it wont accept my password. Anyway:
Does anyone know what the library is for the iPhone’s camera functions and if there is some docs anywhere on accessing it?
Brandon Says:
August 21st, 2008 at 2:14 pm
Why won’t it accept your password? It should have emailed you a temporary password. Sometimes if you do a copy and paste from this email, you get an extra space at the beginning or end that causes an error.
marcus Says:
August 21st, 2008 at 9:25 pm
Thanks for posting the code. I missed the “==” in the nil comparison. I only had a single = sign. If I had a nickel for everytime that has messed me up.
BrewersFan Says:
August 22nd, 2008 at 5:04 pm
All, bobcubsfan, Brandon,
Does anyone know how to change font size / make text in UITableView wrap around? My “Fruit” names in my array are long and I get this:
Applelongfruitname….
BrewersFan
Bob Schoenburg Says:
August 22nd, 2008 at 5:28 pm
Does this help?
http://discussions.apple.com/thread.jspa?threadID=1623586&tstart=70
BrewersFan Says:
August 23rd, 2008 at 5:26 am
Bob,
thanks for post. I am looking to do what is guys is asking. I have looked at the apple sample code on this and still can’t figure out.
It seems like this should be easier to implement..
In my tableview I can change
background color
size of table
but not the font size or create word wrap..
Still confused…
Sam Wilson Says:
August 27th, 2008 at 9:00 am
Awesome tutorials, one question… why did you do this:
IBOutlet UITextView* fruitDescription;
instead of this:
IBOutlet UITextView *fruitDescription;
Are they different?
Brandon Says:
August 27th, 2008 at 11:47 am
Sam,
I did do it like this:
IBOutlet UITextView *fruitDescription;
I don’t think it would compile the way you are suggesting that I coded it.
John Says:
August 27th, 2008 at 12:00 pm
Brandon,
Thanks for the great tutorial. One quick question–how does one change the title of the back button, so that when “Watermelon” is selected, the back button reads something else, like “Index”, instead of “Fruits”?
Any help would be appreciated!
Brandon Says:
August 27th, 2008 at 12:04 pm
The title of the back button is determined by the title of the view you are going “back to”. So if you want it to say Index, title your rootViewController “Index”
So where I have self.title = @”Fruits”; you could change it to self.title = @”Index”;
Hope that helps!
John Says:
August 27th, 2008 at 2:47 pm
Brandon,
Thanks for the help–that works, but it changes the title too. I’m trying to do something like the Facebook app, where it shows “facebook” on the Navigation Bar, but “Profile” or “Chat” once the next view is loaded. Is there any way to disconnect the back button title from the title of the previous view?
John
PS - I was looking at the documentation of the UINavigationItem class and its backButtonTitle property, but I’m pretty new to this and unsure *when* to change this property and from which view controller…
Bob Schoenburg Says:
August 27th, 2008 at 3:42 pm
Try this:
comment the line:
self.fruitView.title = [fruit name];
in RootViewController.m
then and this in FruitViewController
//If you need to do additional setup after loading the view, override viewDidLoad.
- (void)viewDidLoad {
self.title = @”Chat”;
}
Adam Says:
August 31st, 2008 at 4:54 am
Brandon,
Is it necessary to release the NSMutableArray *fruits in dealloc method as shown below?
- (void)dealloc {
[fruits release]
[navigationController release];
[window release];
[super dealloc];
}
john Says:
August 31st, 2008 at 9:11 pm
Great stuff here!
I am trying to extend the fruit example, with only 1 change, but that is enough to stump me
I just want to have 2 UITableViews on the main page (each 1/2 of the view). Is this possible starting with the ‘nav based app’ that we are using for the fruit example? I am not sure how to change the name of the original one ‘tableView’ If I could rename it to toptableView, I might be able to figure it out
Any pointers from anyone?
Brandon Says:
August 31st, 2008 at 9:38 pm
@Adam,
Its not necessary but great practice. I was a little lazy and should have put it in. Great catch!
Jim Says:
September 4th, 2008 at 1:01 pm
First of all: thanks for this great tutorials. It’s very helpful for me!
Following the tutorial, I created the Fruit project. Everything was fine until I pushed a fruit item from the fruit table. I got the following problems.
Fruit[6749] *** Assertion failure in -[UILabel setTextColor:], /SourceCache/UIKit/UIKit-738/UILabel.m:288
Fruit[6749] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Invalid parameter not satisfying: color’
Any pointers to this are appreciated?
Jim
Jon K Says:
September 6th, 2008 at 4:07 pm
Again, great tutorial! Thank you!
1 suggestion. In the ‘didSelectRowAtIndexPath’ method I set the title and description of the fruitView first, then added it to the navigationController stack. If you add the view to the stack first, you will see the title of a previously viewed fruitView just for a split second and then it will change the title.
AndyB Says:
September 20th, 2008 at 10:33 am
@Jon K
I just tried the change you suggested and changed the code in didSelectRowAtIndexPath to look like this:
self.fruitView.title = [fruit name];
[self.fruitView.fruitDescription setText:[fruit description]];
[self.navigationController pushViewController:self.fruitView animated:YES];
It fixes the problem with the title display but…
The problem is that when I run the app the first time I click on a fruit the description is blank. After that every time a fruit is selected the correct description is shown.
Is there something else I need to change to make this work?
Thanks.
corey Says:
September 22nd, 2008 at 2:37 pm
In the method:
- (void)viewDidLoad
you delete the line where you call super:
[super viewDidLoad];
Is it not necessary to call super if you implement the method?
Thanks for al the help on your blog….
Brandon Says:
September 22nd, 2008 at 3:49 pm
It’s good practice, because it will be required if you overwrite more complex functionality. However, it’s not 100% necessary.
billgajen Says:
September 23rd, 2008 at 2:23 am
Hi,
Its amazing.. It helps me a lot. Thank you so much.
But I have doubt,
How to do like UITableView to UITableView..
I mean, in the table when you tab on a cell that should bring another table. for example 1st one is main menu then when you choose one that should give you a submenu! I know its possible
but if can let us know pls
Pls
Mike Says:
September 26th, 2008 at 7:30 am
Brandon - thanks for the example…..I do have one question though. I am trying to show two fields in the cell.text and seem to be having problem….basically, this is what I am trying to do:
cell.text = f.firstname && f.lastname;
Question is - how do I concatenate two fields in C - I am not too familiar with C. Also what if one of these fields was a date field?
For eg:
cell.text = f.name && f.dateofbirth
Thanks for your help!!
Mike
Brandon Says:
September 26th, 2008 at 8:09 am
@Mike,
Appending strings in Objective-C is a little different than in other languages. I don’t know why Apple just didn’t make it so you would write String foo = foo + bar.
So to append string you would do something like this:
NSString *name = [[NSString alloc] initWithString:f.firstname];
[name stringByAppendingString:f.lastname];
cell.text = name;
Does this make sense? It’s quite a bit of code just to append a string to another string. Let me know if you need more help.
billgajen Says:
September 27th, 2008 at 4:02 am
Hi brandon,
Why you ignored my qustion?
I am trying to do some thing in apps. as a beginner I need some help
pls help me
Brandon Says:
September 27th, 2008 at 7:42 am
@billgajen
Sorry, it took me so long to respond. The question you are asking would take more than just a few sentences to answer. In fact, I could do an entire tutorial on it.
I get a lot of requests for such a functionality and will consider doing a tutorial on it in the future.
theluiz Says:
September 28th, 2008 at 2:31 pm
Hello…
I followed your code exactly only naming all the variables and files differently, and there are no errors or warning when building; however the UITableView is empty! :O
I looked through the code and found no differences to your code (only with my variables)… Please help! ![]()
theluiz Says:
September 28th, 2008 at 2:42 pm
ahh nvm found it…
forgot the
return self;
in
- (id)initWithName:(NSString*)n subject:(NSString *)subj description:(NSString *)desc duedate:(NSString *)due {
![]()
Brandon Says:
September 28th, 2008 at 2:48 pm
@theluiz,
haha nice. It’s always something simple… I’m glad you were able to get it working.
iPhone Application And Website Development: All Tools And Tutorials You Need | Athena Design - The Lounge Says:
September 29th, 2008 at 12:26 am
[...] Populating UITableView With An NSArray [...]
theluiz Says:
September 29th, 2008 at 8:15 am
QUESTION : ![]()
how would i add an object to this array? thanks in advance!
Brandon Says:
September 29th, 2008 at 9:19 am
@theluiz,
It’s pretty simple.
Fruit *peach = [[Fruit alloc] initWithName:@”peach” description:@”fuzzy on the outside”];
[self.fruits addObject:peach];
Does this make sense? I’m on the city bus responding from my iPhone so sorry if there are any typos. Let me know if you need more help.
theluiz Says:
September 29th, 2008 at 9:38 am
ah ok makes perfect sense… thanks alot for the replies!
theluiz Says:
October 1st, 2008 at 6:43 am
ok one more question (maybe the last ^_^)…
how would i add an uiimage to the list of
NSString *name;
NSString *description;
such that when i add an object to the array, i just need to specify
initWithName:@”hello” description:@”hi” picture:@”icon.png”
and i could then simple set a uiimageview to this image? sorry if im not making sense ![]()
wmparry Says:
October 1st, 2008 at 6:53 am
Hi,
I know this is a bit of an old subject, but just working through the tutorial and I’ve got stuck on the Connection Inspector part. I can’t get the fruitDescription Outlet to connect to the UITextView. I can connect the View to the FruitViewController, but the former just won’t play. I’ve double checked my code in FruitViewController.h and .m and I can’t spot any error except that my *fruitDescription is grey shaded like the screen shot.
Thanks in advance for any advice. Great tutorials though.
Brandon Says:
October 1st, 2008 at 9:48 am
@wmparry
Did you make sure and complete the step when you select FruitViewController from the drop down on the Identity Inspector of the File’s Owner object? This would be the first thing I would check.
@theluiz,
in Fruit.h
// Declare the UIImageView
UIImageView *picture;
// Make it a property
@property(nonatomic,retain) UIImageView *picture;
// Modify the initWithName method signature
-(id)initWithName:(NSString *)n description:(NSString *) desc picture:(UIImageView *) pic;
in Fruit.m
// synth the UIImageView
@synthesize picture;
// Update the initWithNameMethod
-(id)initWithName:(NSString *)n description:(NSString *) desc picture:(UIImageView *) pic {
self.picture = pic;
……
}
That should do it!
theluiz Says:
October 1st, 2008 at 10:53 am
ok so i made picture blank.png in my object that gets created on startup, however in didSelectRowAtIndex i put this
[self.workView.workPic initWithImage:[homework picture]];
and it does not work… i also tried this
[self.workView.workPic setImage:[homework picture]];
with no luck ![]()



























