Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

UITableView Tutorial Part #2

myersn024myersn024 Posts: 315Tutorial Authors
edited February 2011 in iPhone SDK Tutorials
The second part of my UITableView series is finished and uploaded.

This tutorial covers how to add a new item button and an edit button to the navigation bar, how to commit editing and row deletion, and how to add new elements to the content array and update the table view after doing so. This tutorial is about 12:00 minutes long and uses the source code from the first part as the starting place.

<object width="800" height="490"> <param name="allowfullscreen" value="true" /> <param name="allowscriptaccess" value="always" /> <param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1680510&server=vimeo.com&show_title=1&show_byline=0&show_portrait=0&color=00ADEF&fullscreen=1" /> <embed src="http://vimeo.com/moogaloop.swf?clip_id=1680510&server=vimeo.com&show_title=1&show_byline=0&show_portrait=0&color=00ADEF&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="800" height="490"></embed></object><br /><a href=" ">iPhone Tutorial - UITableViews Part #2</a> from <a href="http://vimeo.com/user647705?pg=embed&sec=1680510">Nick Myers</a> on <a href="http://vimeo.com?pg=embed&sec=1680510">Vimeo</a>.
<a href=http://vimeo.com/download/video:85123959?e=1220757056&h=934a5bd2544eaca8bf667b79e825d0ed>Download the HiDef version to your computer</a>

The next tutorial will probably go over creating custom cells.

You can go ahead and download the source code if you'd like.
Post edited by myersn024 on

Replies

  • ChriBChriB Posts: 154Registered Users
    edited September 2008
  • Vortec4800Vortec4800 Posts: 160Registered Users
    edited September 2008
    Great! I used this tutorial to get my Table view working great. I do have a small problem though, the animation that happens in the simulator when I remove an item from the list is very strange. It almost looks like it mixes the items up but they still appear in the correct order. Does the same thing happen to you, is there a way to clean up the animation?

    Looking forward to the next edition! I'd like to make the add button bring up another window (maybe use an animation to flip the box around like your multiple XIB tutorial) which asks for some info before going adding the object. I also want to edit my cell to show some more info, or maybe have it so that when I select an item it brings up a "more info" box with related data about the object.
  • myersn024myersn024 Posts: 315Tutorial Authors
    edited September 2008
    Same thing happens on the actual device sometimes too. Just play around with the row animations until you find one you like....or one you dislike the least.
  • spazthecatspazthecat Posts: 14Registered Users
    edited November 2008
    Great tutorial! Thank you for working on this and your other tutorials. I've found them all very helpful.

    I was wondering if you had anything on how to add an insert row at the end of a table view (one with the little green plus sign when you hit the "Edit" button) rather than putting an insert button in the navigation bar? I have a basic table view that when in edit mode, I'd like to have an "Add new item ...." entry at the beginning or end of the data list.

    I've figured out how to have a particular row display the green plus sign and load the view I want but I can't figure out how to only display the "Add new item...." row when in edit mode.

    Thanks,
    Andy
  • kienNakienNa Posts: 4New Users
    edited December 2008
    I am a newbie in iPhone software development. Recently I am working on a small application for iPhone that uses tableview control. My application displayed a list of data fine the first time when it came up, but when I scrolled up and down, the data in some cells got overrided. When I selected those cells, its data was overlapped by data of the next cells. It seemed that when I scrolled, the function - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath got called many times. Here is the function:

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

    static NSString *CellIdentifier = @"MyIdentifier";
    //CGRect cellRect = CGRectMake(0.0, 0.0, tableView.bounds.size.width, 100);
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...
    NSDictionary *itemAtIndex = (NSDictionary *)[dataController objectInListAtIndex:indexPath.row];
    NSString *text = [itemAtIndex objectForKey:@"originalQuote"];
    CGSize textSize = {tableView.bounds.size.width - 5, 80.0f};
    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:13.0f]constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];
    CGRect contentRect = CGRectMake(5.0, 5.0, tableView.bounds.size.width - 5, size.height);
    UILabel *textView = [[UILabel alloc] initWithFrame:contentRect];
    textView.text = text;
    textView.font = [UIFont systemFontOfSize:13];
    textView.lineBreakMode = 0;
    textView.numberOfLines = 10;
    textView.textColor = [UIColor blackColor];
    [cell.contentView addSubview:textView];

    [text release];
    [textView release];

    return cell;
    }

    Can anyone please show me what I am doing wrong or what may be wrong in my application? Thanks a lot.
  • jeremieweldinjeremieweldin Posts: 29Registered Users
    edited December 2008
    You are adding new labels every time the method gets called. Instead, add the labels/controls only when creating a new cell and then call them out by tag in order to modify their values for the current cell being painted.
    #define WHAT_TAG 1
    
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        
        static NSString *CellIdentifier = @"Cell";
        
        UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    		cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    		cell.selectionStyle = UITableViewCellSelectionStyleNone;
    		
    		UILabel *what;
    		
    		what = [[[UILabel alloc] initWithFrame:CGRectMake(5, 0.5, 240.0, 25.0)] autorelease];
    		what.tag = WHAT_TAG;
    		what.font = [UIFont boldSystemFontOfSize:14.0];
    		what.textAlignment = UITextAlignmentLeft;
    		what.textColor = [UIColor blueColor];
    		what.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
    		what.backgroundColor = [UIColor clearColor];
    		[cell.contentView addSubview:what];
    		
        }
    		
    	Gift *gift = (Gift *)[self.gifts objectAtIndex:indexPath.row];
    	
    	UILabel *whatLabel;
    	whatLabel = (UILabel *)[cell viewWithTag:WHAT_TAG];
    	whatLabel.text = gift.what;
    
    	
    	return cell;
    }
    
    
    <a href="http://itunes.com/app/SantasLittleHelper" target="_blank">Santa's Little Helper</a><br />
    <a href="http://itunes.com/app/SwiftTally" target="_blank">SwiftTally</a><br />
    <a href="http://itunes.com/app/StatePlateHunt" target="_blank">State Plate
  • kienNakienNa Posts: 4New Users
    edited December 2008
    Thank you Jeremieweldin. Yesterday I made it work by disable the reusable cell by setting dequeueReusableCellWithIdentifier:nil and reuseIdentifier:nil. But I think your solution is better, I will give it a try.
  • Duncan CDuncan C Posts: 9,029Tutorial Authors, Registered Users @ @ @ @ @ @ @
    edited December 2008
    kienNa wrote: »
    Thank you Jeremieweldin. Yesterday I made it work by disable the reusable cell by setting dequeueReusableCellWithIdentifier:nil and reuseIdentifier:nil. But I think your solution is better, I will give it a try.

    kienNa,

    You do NOT want to disable cell reuse. This will cause your application to come to a screeching halt at some point. The memory use of your application will rise to the point where it won't run any more, or the system may force it to shut down.

    Getting the hang of cell reuse is tricky. I struggled with it also.

    What you do is to ask for a re-used cell, and if that fails, create a new cell and new instances of the child views that belong to the cell. You plug the views and other objects into the cell so that it becomes a complete functioning unit.

    In your cellForRowAtIndexPath method, you want to set ALL the values for the cell you are creating. The cell may be a new cell, or it may be a cell that has scrolled off-screen and is being recycled. Set tags on any fields that handle touch events, set text field values, etc.

    This is quite confusing, but you need to struggle through it and get it working correctly with cell reuse turned on. Once you get the hang of it it's pretty easy.
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • kienNakienNa Posts: 4New Users
    edited January 2009
    Duncan,

    Thanks for your advices. I followed your advices as well as Jeremieweldin example and made it work. I created different identifiers for different cells and only created new cells when I could not find the old cells. It seems working.
  • jeremieweldinjeremieweldin Posts: 29Registered Users
    edited January 2009
    Great to hear!
    <a href="http://itunes.com/app/SantasLittleHelper" target="_blank">Santa's Little Helper</a><br />
    <a href="http://itunes.com/app/SwiftTally" target="_blank">SwiftTally</a><br />
    <a href="http://itunes.com/app/StatePlateHunt" target="_blank">State Plate
  • kevmcdkevmcd Posts: 24Registered Users
    edited February 2009
    Nice tutorial. Tried to run the sample code and the delete fails.

    Looks like the line

    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];

    Is not valid in 2.2.1
  • DroopyDroopy Posts: 1New Users
    edited April 2009
    Yeah, the sample code crashes at deleteRowsAtIndexPaths for 2.2 and later:

    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update, plus or minus the number of rows added or removed from that section (3).'

    To fix it, the following line should be moved before the deleteRowsAtIndexPaths line:

    [[delegate contentArray] removeObjectAtIndex:indexPath.row];
  • RobertD63RobertD63 Posts: 53Registered Users
    edited May 2009
    How would I do this in a top scores kinda thing? I wanna add a top scores part to my Reaction Time App.
  • adeemadeem Posts: 34Tutorial Authors
    edited May 2009
    Adeem<br />
    For Tutorials on iPhone check out <a href="http://adeem.me/blog" target="_blank">http://adeem.me/blog</a><br />
    iPhone Tutorial on Demand!
  • beeferbeefer Posts: 10Registered Users
    edited February 2011
    I know this is an ancient thread but I came across it whilst searching for help with this topic. The sample code still works on latest OS and Xcode subject to Droopy's solution.
Sign In or Register to comment.