user1776234
user1776234

Reputation:

UITableView refusing to go to detailViewController

Edit: This question has been moved to Getting an error from Xcode that is not on the internet related to index path because this question was fixed but presented with a new error.

I have been at this for 4 days! I am getting no errors in the log, yet whenever I click on my cell that is populated with a dynamic array downloaded from mysql, it does not transition. Interestingly, I got no response from the self placed nslogs in prepareForSegue...

ViewController.h

   #import <UIKit/UIKit.h>
    #import <CoreLocation/CoreLocation.h>


@interface ViewController : UIViewController<UITableViewDataSource,
 CLLocationManagerDelegate,NSXMLParserDelegate, UISearchBarDelegate> {
    IBOutlet UISearchBar *searchBar;
    IBOutlet UITableView *tableView;
     IBOutlet UILabel *Label;


    CLLocationManager *locationManager;

    NSMutableArray *coolarray;

    float latitude;
    float longitude;
}



@property (nonatomic, retain) CLLocationManager *locationManager;


@end

I've excluded the xml downloaded data that was parsed, but left the values for the nsarray below in my implementation file

   #import "ViewController.h"
    #import "DetailViewController.h"
    #import "Player.h"

    @interface ViewController ()

    @end

    @implementation ViewController



    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    - (void)dealloc
    {
        [super dealloc];
        [self.locationManager release];
        if ( coolarray )
            [coolarray release];
    }

    - (void)viewDidLoad
    {
        [super viewDidLoad];

        coolarray = NULL;

        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
        [self.locationManager startUpdatingLocation];
    }

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return YES;
    }

    // Table data delegate
    - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
        if ( coolarray != NULL ) {
            return [coolarray count];
        }
        return 0;
    }

    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
            Player *cell = [tableView dequeueReusableCellWithIdentifier:@"Player"];

        if (cell == nil)
        {
            cell = [[[Player alloc] initWithFrame:CGRectZero reuseIdentifier:@"Player"] autorelease];
        }


        NSDictionary *itemAtIndex = (NSDictionary *)[coolarray objectAtIndex:indexPath.row];
        UILabel *nameLabel =[cell textLabel];
        [nameLabel setText:[itemAtIndex objectForKey:@"name"]];
        return cell;
    }
                - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
                        Player *cell = [tableView dequeueReusableCellWithIdentifier:@"Player"];

                    if (cell == nil)
                    {
                        cell = [[[Player alloc] initWithFrame:CGRectZero reuseIdentifier:@"Player"] autorelease];
                    }


                    NSDictionary *itemAtIndex = (NSDictionary *)[coolarray objectAtIndex:indexPath.row];
                    UILabel *nameLabel =[cell textLabel];
                    [nameLabel setText:[itemAtIndex objectForKey:@"name"]];
                    return cell;
                }

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

            NSString *selectedLang = [coolarray objectAtIndex:indexPath.row];


            DetailViewController *myDetViewCont = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:[NSBundle mainBundle]]; 

            myDetViewCont.myDogLang = selectedLang; 
            [self  performSegueWithIdentifier:@"showDogDetail" sender:nil];

            [myDetViewCont release]; 
            myDetViewCont = nil;

        }

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{ 
    if ([[segue identifier] isEqualToString:@"showDogDetail"])
    {
        DetailViewController *detailViewController =
        [segue destinationViewController];

        NSIndexPath *indexPath = [self.tableView
                                    indexPathForSelectedRow];
        NSString *dogLang = [self.coolarray objectAtIndex:indexPath.row];
        detailViewController.myDogLang = dogLang;
                    }

            }
@end

DetailViewController.h

#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController
 {

    IBOutlet UILabel *myLabel;

    NSString *myDogLang;

}

@property (nonatomic, retain) IBOutlet UILabel *myLabel;
@property (nonatomic, retain) NSString *myDogLang;

@end

DetailViewController.m

#import "DetailViewController.h"

@interface DetailViewController ()

@end

@implementation DetailViewController
@synthesize myLabel;
@synthesize myDogLang;

- (void)viewDidLoad {
    [super viewDidLoad];
    myLabel.text = myDogLang;
        self.myLabel.text = [self.myLabel objectAtIndex:0];
}

- (void)dealloc {
    [myLabel release];
    [myDogLang release];
    [super dealloc];
}

I've also added a picture to show my connection: enter image description here

Upvotes: 0

Views: 1304

Answers (2)

J Shapiro
J Shapiro

Reputation: 3861

It looks like you're mixing and matching a few different styles here... I suggest simplifying your code:

1) Delete the current segue between the table and detail view. Create a new one by holding the control key and dragging from the prototype cell (I'm assuming this is a prototype table) to the destination view. Don't forget to name the identifier the same name you are using in your prepareForSegue code). Also, if you have the table view controller embedded in a Navigation controller (which is what is typically expected on a navigable table view), the style of the segue should be 'Push.' Otherwise the style should be 'Modal' (though, depending on the usability of your app, you may want to reconsider this approach).

enter image description here

2) What's going on with the Player class? Is this a class that extends UITableViewCell? When you click on the prototype cell in the storyboard, what class is listed in the identity inspector? Is it Player or UITableViewCell? What is the identifier of the cell in the attribute inspector? Is it Player or blank (given your code, it needs to be "Player")? Try taking the Player class, at least temporarily, out of the picture. Keep the identifier of the cell as Player, but in the identity inspector, set the custom class of the prototype cell to UITableViewCell. Change your tableView:cellForRowAtIndexPath: method to:

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Player"];

    NSDictionary *itemAtIndex = (NSDictionary *)[self.coolarray objectAtIndex:indexPath.row];
    cell.textLabel.text = [itemAtIndex objectForKey:@"name"];
    return cell;
}

Also as a side note here, you're indicating in this method that the members of coolarray are an NSDictionary type. In prepareForSegue you are treating the members of coolarray as NSStrings. They can't be both.

3) Get rid of the tableView:didSelectRowAtIndexPath: method. This is important. You have two competing methods of segues happening here. One that is set up in the Storyboard and this method. The way your code is written right now, a click on the cell will call prepareForSegue -> didSelect -> prepareForSegue. Everything that you are attempting to do in here can be done in the prepareForSegue: method (see the next step).

4) Change your prepareForSegue: method to look something like this (you could even get rid of the "if" statement since you only have one segue right now):

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{ 
    if ([[segue identifier] isEqualToString:@"showDogDetail"])
    {
        DetailViewController *detailViewController =
        [segue destinationViewController];

        NSIndexPath *indexPath = [self.tableView
                                    indexPathForSelectedRow];
        NSString *dogLang = [self.coolarray objectAtIndex:indexPath.row];
        // or if the array contains NSDictionaries, change the previous line to:
        // NSString *dogLang = [[self.coolarray objectAtIndex:indexPath.row] objectForKey:@"name"];
        detailViewController.myDogLang = dogLang;
    }
}

5) Your DetailViewController's viewDidLoad method is overriding the label text with some bad code (a UILabel is not an array). Change the code to:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.myLabel.text = self.myDogLang;
}

Given some of the conceptual issues I've mentioned above, I highly recommend reading Apple's Table View Programming Guide. It'll help clarify the life cycle and flow for you.

Upvotes: 1

LombaX
LombaX

Reputation: 17364

1- you should choose which approach you want to use: segue with connection inside the storyboard or a programmatically loaded detail controller (using didSelectRowAtIndexPath). Now you are doing both things: no good. Try to comment all your didSelectRowAtIndexPath code and use only storyboard. Moreover, in your didSelectRowAtIndexPath you are loading detail vc from a nib??? Which nib? You don't have nibs, you have a storyboard! (You can programmatically load things from storyboard, but the code is different)

2- if you use Push for the segue, you MUST HAVE an UINavigationController in your storyboard. Put the nav controller, when you place it in the storyboard it comes with a UITableViewController attached. Remove this UITV and attach yours. Reconnect the cell to the detail controller and remember to give an identifier name to the connection, be sure that the connection starts from the cell. I'm not sure if you need UINavigationController even for the modal segue.

Try and let me know

Upvotes: 0

Related Questions