Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Blog Reader iPhone App Viewing a Web Page Opening a Web Page in Safari

Weird error that requires 2 rows to be selected on screen

I am getting a weird bug when using didSelectRowAtIndexPath. When implementing the method and running the simulator, I am required to click on a 2nd row before the 1st row I selected will be recognized. For example, the table view comes up with all the blog entries listed. I click on the post for Feb 21, but nothing happens. Then I click on the post for Feb 22, and then the web page comes up for the post for Feb 21 - the first selection! And now if I click on Feb 26, the post for Feb 22 comes up!
And just as weird, if I click on the same post twice, Feb 26, nothing happens, as I have to click on a completely different post to get the Feb 26 post to come up. This same bug happened earlier in the lesson using the NSLog call to verify the clicks. Any ideas? Thx

7 Answers

Mike Baxter
Mike Baxter
4,442 Points

Oh. Oh I see.

The problem is that you're using "did*DeselectRowAtIndexPath" to trigger the open URL request. You need to handle that in the "didSelect*RowAtIndexPath".

Do you see? Imagine you have two rows in your UITableView, Row A and Row B. Suppose you tap on Row A. Row A's cell gets sent the message "did*SelectRowAtIndexPath". This would be the ideal time to handle any view loading. Now let's suppose you tap on Row B next. Row A becomes *deselected so that Row B can become selected. So Row A gets sent the message "did*DeselectRowAtIndexPath", and Row B gets sent the message "didSelect*RowAtIndexPath".

That would also explain why tapping on the same row many times in sequence never triggers the page to load—it never gets deselected, and your code is telling to to only open on a deselect.

All you have to do is change the name Deselect to Select and you should be good!

(As an aside, you might also want to test what happens when your thumbnail image doesn't exist. Does it load or not? I'm not sure.)

Mike Baxter
Mike Baxter
4,442 Points

Yeah, can you post the code for didSelectRowAtIndexPath as well as the code for your table view's data source?

My guess is there's some indexing issue going on. There are two main ways in which your indexing could be messed up:

  1. In the didSelectRowAtIndexPath, you're not using [indexPath row] correctly.
  2. Your table view's data array is messed up. Maybe you started indexing it at [1] instead of [0]? (That would explain things being offset incorrectly.)

You can always try getting a description of the first element of your data source; if it's an array, you can do the following:

NSLog(@"%@", [[myArray objectAtIndex:0] description]);

Basically you want to check to see if it's actually defined. You might even try outputting the titles for each object in the tableview's array; something like this:

for (int i=0; i < [myArray count]; i++) {
    NSLog(@"%d = %@", i, [[myArray objectAtIndex:i] description]);
}

Which should output something like this (if the array contains strings):

0 = NULL
1 = Feb 21
2 = Feb 22
3 = Feb 26

You should see 0 = to something other than NULL. (I'm not sure if it will actually output NULL, it may say something else.)

Hi, code to follow ( I am having trouble with formatting)

'''

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    DSBlogPost *blogPost = [self.blogPosts objectAtIndex:indexPath.row];

    if ([blogPost.thumbnail isKindOfClass:[NSString class]]) {

    NSData *imageData = [NSData dataWithContentsOfURL:blogPost.thumbnailURL];

    UIImage *image = [UIImage imageWithData:imageData];

    cell.imageView.image = image;
    } else {
        cell.imageView.image = [UIImage imageNamed:@"Nightwing logo.png"];
    }

    cell.textLabel.text = blogPost.title;

    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", blogPost.author, [blogPost formattedDate]];

   return cell;
 }

'''

and here: '''

    -(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {

    DSBlogPost *blogPost = [self.blogPosts objectAtIndex:indexPath.row];

    UIApplication *application = [UIApplication sharedApplication];
    [application openURL:blogPost.url];

    }

'''

Nice catch Mike!