views:

39

answers:

2

I have a TableView setup as my "root view controller" and a detail view controller called "DetailController" to allow me to display the detail view for what the user selects in the main table view. The navigation is working correctly - when I select a row in my table the screen slides to the left and I'm presented with my detail view, but I can't update the detail view's UILabel text properties. It's like it is just ignoring my UILable set property methods (see code below) as it isn't giving me any errors or warnings.

I've tested that I do have the values I need when I hit the "tableView:didSelectRowAtIndexPath:" method, but for some reason I can't seem to update the detail view's UILabels' text properties. Using NSLog's I can see that I am getting the values and passing them correctly to the UILabels. However the detail view isn't showing the passed values in its UILabels.

The strange thing is that I CAN set the detail view's title property correctly, just not the UILabel properties, which is very confusing!

Here's my code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.

if (self.detailView == nil) {
    DetailController *detail = [[DetailController alloc] initWithNibName:@"DetailController" bundle:nil];
    self.detailView = detail;
    [detail release];
}

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:[theList getItem:cell.textLabel.text]];

[self.detailView.theID setText:@"LOOK AT ME NOW!"];

self.detailView.thePrice.text = [[dict objectForKey:@"PRICE"] stringValue]; 

// Pass the selected object to the new view controller.
[self.navigationController pushViewController:self.detailView animated:YES];

NSString *newTitle = [[NSString alloc] initWithString: @"Viewing Attributes for: "];
newTitle = [newTitle stringByAppendingString:cell.textLabel.text];
self.detailView.title = newTitle;
[dict release];
[newTitle release];
}

Thanks for any help on this! I love this community - you guys are awesome!


I Found An Answer! I think...

After much trial and error I was able to figure out a solution, but the solution doesn't entirely make sense to me and still leaves me with questions.

Siegfried suggested that I move my "pushViewController" message to the end of the method so that the last six lines of my code were changed to:

    // Pass the selected object to the new view controller.
NSString *newTitle = [[NSString alloc] initWithString: @"Viewing Attributes for: "];
newTitle = [newTitle stringByAppendingString:cell.textLabel.text];
self.detailView.title = newTitle;
[dict release];
[newTitle release];
[self.navigationController pushViewController:self.detailView animated:YES];
}

When I moved it to the last line (as shown above) my program would crash with an EXC_BAD_ACCESS error. I still don't understand why moving that line of code to the end of my method caused the program to crash?

However, this got me thinking - I was able to successfully change the title of the new detail view, but not the view's UILabel properties. So I moved my pushViewController method back to where it was and then moved my methods for setting the new view's UILabels underneath the pushViewController method and BOOM! Everything worked! The new detail view was being pushed when the user clicked on the row in my table and its properties (title and UILabels) were all being set correctly.

Why does this work?

I remember reading about how the iPhone handles views, something called "lazy loading" or "lazy instantiation"? I think this means that I can't change the properties of my detail view UNTIL I've "pushed" it, which is when the object is actually created in memory and its properties become available?

If this is correct, that would kind of explain the error I was getting when I moved the pushViewController method to the end of my code - I was trying to change the title property on a view that wasn't instantiated. However, that doesn't completely make sense because I was trying to change the UILabel properties of the view in my original code, which was before the view was actually pushed and the program wasn't crashing?

So my code that is currently working looks like the following:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.

if (self.detailView == nil) {
    DetailController *detail = [[DetailController alloc] initWithNibName:@"DetailController" bundle:nil];
    self.detailView = detail;
    [detail release];
}

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:[theList getItem:cell.textLabel.text]];

// Pass the selected object to the new view controller.
[self.navigationController pushViewController:self.detailView animated:YES];

// Moved the "set property" methods to happen after the detail view is pushed
[self.detailView.theID setText:@"LOOK AT ME NOW!"];
self.detailView.thePrice.text = [[dict objectForKey:@"PRICE"] stringValue];     
NSString *newTitle = [[NSString alloc] initWithString: @"Viewing Attributes for: "];
newTitle = [newTitle stringByAppendingString:cell.textLabel.text];
self.detailView.title = newTitle;
[dict release];
[newTitle release];
}

I like that the code is working, but I would really like to understand what was and is actually happening. Can anyone offer additional insight here?

Thank you!

+2  A: 

Move

[self.navigationController pushViewController:self.detailView animated:YES]; 

to last line.

sza
Doing this causes the program to crash and give me a "Program received signal: "EXC_BAD_ACCESS" error?
Zigrivers
A: 

You may try doing:

NSString *strText = [NSString stringWithFormat:@"%@",[[dict objectForKey:@"PRICE"] stringValue]];
self.detailView.thePrice.text = [NSString stringWithFormat:@"%@",strText];

Check wheather strText is containing the expected value and is not nil.

neha