Question

I am trying to push data in an array to a new UITableView. I have completed the code and there are no errors, but it is pushing to a blank view (not pushing array data to new view).

When the user presses "Alabama Area 1" it should pull up the 3 climbs in that area that are in the alabamaArea1 array and the same thing for "Alabama Area 2". It is not pushing the data though. I will post my code below.

RootTableViewController.h:

#import <UIKit/UIKit.h>

@interface RootTableViewController : UITableViewController

@end

RootTableViewController.m:

#import "RootTableViewController.h"
#import "SecondTableViewController.h"

@interface RootTableViewController ()

@end

@implementation RootTableViewController
{
NSArray *states;
}

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

states = [NSArray arrayWithObjects:@"Alabama", @"Georgia", @"Tennessee", @"Colorado", nil];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [states count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//table identifier
static NSString *simpleTableIdentifier = @"StateCell";

//creating a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

//if cell doesn't have anything in it, creates a new one
if(cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

//creates text for cell, depending on what row it is
cell.textLabel.text = [states objectAtIndex:indexPath.row];

return cell;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//push segue identifier 'showArrayDetail'
if([segue.identifier isEqualToString:@"showStateDetail"])
{
    //row that we clicked on
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

    //'SecondTableVieController' object is created
    SecondTableViewController *destViewController = segue.destinationViewController;

    //sets 'stateName' to what row you pick
    destViewController.stateName = [states objectAtIndex:indexPath.row];

    //sets title to 'stateName' you picked
    destViewController.title = [NSString stringWithFormat:@"%@ Areas", destViewController.stateName];
}
}

@end

SecondTableViewController.h:

#import <UIKit/UIKit.h>

@interface SecondTableViewController : UITableViewController

@property (nonatomic, strong) NSString *stateName;

@end

SecondTableViewController.m:

#import "SecondTableViewController.h"
#import "ThirdTableViewController.h"

@interface SecondTableViewController ()

@end

@implementation SecondTableViewController
{
NSArray *alabama;
NSArray *georgia;
NSArray *tenesssee;
NSArray *colorado;

NSArray *areas;
}

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

//populating arrays
alabama = [NSArray arrayWithObjects:@"Alabama Area 1", @"Alabama Area 2", @"Alabama Area 3", nil];
georgia = [NSArray arrayWithObjects:@"Georgia Area 1", @"Georgia Area 2", @"Georgia Area 3", nil];
tenesssee = [NSArray arrayWithObjects:@"Tennessee Area 1", @"Tennessee Area 2", @"Tennessee Area 3", nil];
colorado = [NSArray arrayWithObjects:@"Colorado Area 1", @"Colorado Area 2", @"Colorado Area 3", nil];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//returns number of rows dependent on which state was selected
if([_stateName isEqualToString:@"Alabama"])
{
    return [alabama count];
}

else if([_stateName isEqualToString:@"Georgia"])
{
    return [georgia count];
}

else if([_stateName isEqualToString:@"Tennessee"])
{
    return [tenesssee count];
}

else if([_stateName isEqualToString:@"Colorado"])
{
    return [colorado count];
}

return 0;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//table identifier
static NSString *simpleTableIdentifier = @"AreaCell";

//creating a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

//if cell doesn't have anything in it, creates a new one
if(cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

//depending on what string equals depends on what array values are displayed
if([_stateName isEqualToString:@"Alabama"])
{
    cell.textLabel.text = [alabama objectAtIndex:indexPath.row];
}

else if([_stateName isEqualToString:@"Georgia"])
{
    cell.textLabel.text = [georgia objectAtIndex:indexPath.row];
}

else if([_stateName isEqualToString:@"Tennessee"])
{
    cell.textLabel.text = [tenesssee objectAtIndex:indexPath.row];
}

else if([_stateName isEqualToString:@"Colorado"])
{
    cell.textLabel.text = [colorado objectAtIndex:indexPath.row];
}

return cell;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//push segue identifier 'showArrayDetail'
if([segue.identifier isEqualToString:@"showAreaDetail"])
{
    //row that we clicked on
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

    //'SecondTableVieController' object is created
    ThirdTableViewController *destViewController = segue.destinationViewController;

    //sets 'areaName' to what row you pick
    destViewController.areaName = [areas objectAtIndex:indexPath.row];

    //sets title to 'areaName' you picked
    destViewController.title = [NSString stringWithFormat:@"%@ Climbs", destViewController.areaName];
}

}

@end

ThirdTableViewController.h:

#import <UIKit/UIKit.h>

@interface ThirdTableViewController : UITableViewController

@property (nonatomic, strong) NSString *areaName;

@end

ThirdTableViewController.m:

#import "ThirdTableViewController.h"

@interface ThirdTableViewController ()

@end

@implementation ThirdTableViewController
{
NSArray *alabamaArea1;
NSArray *alabamaArea2;
}

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

//populating arrays
alabamaArea1 = [NSArray arrayWithObjects:@"Alabama Climb 1", @"Alabama Climb 2", @"Alabama Climb 3", nil];
alabamaArea2 = [NSArray arrayWithObjects:@"Alabama Climb 4", @"Alabama Climb 5", @"Alabama Climb 6", nil];

// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;

// Uncomment the following line to display an Edit button in the navigation bar for this view  controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//returns number of rows dependent on which state was selected
if([_areaName isEqualToString:@"Alabama Area 1"])
{
    return [alabamaArea1 count];
}

else if([_areaName isEqualToString:@"Alabama Area 2"])
{
    return [alabamaArea2 count];
}

return 0;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//table identifier
static NSString *simpleTableIdentifier = @"ClimbCell";

//creating a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

//if cell doesn't have anything in it, creates a new one
if(cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault     reuseIdentifier:simpleTableIdentifier];
}

//depending on what string equals depends on what array values are displayed
if([_areaName isEqualToString:@"Alabama Area 1"])
{
    cell.textLabel.text = [alabamaArea1 objectAtIndex:indexPath.row];
}

else if([_areaName isEqualToString:@"Alabama Area 2"])
{
    cell.textLabel.text = [alabamaArea2 objectAtIndex:indexPath.row];
}

return cell;

}

I have tested my code out and the problem seems to be coming from the cellForRowAtIndexPath method. I am not looking for someone to hold my hand and tell me the answer, just some proper guidance and contrastive criticism.

Thanks

Was it helpful?

Solution

Your problem is a simple one - you never created the areas object in your SecondTableViewController, so it's nil when you call [areas objectAtIndex:indexPath.row]in prepareForSegue. The code you have in the SecondTableViewController (and in the third one too) could be greatly simplified by using a single dictionary with the state names as the keys and the array of areas as the values instead of the separate arrays. Here's a simplified version of that controller's code,

@implementation SecondTableViewController {
    NSArray *areas;
}


- (void)viewDidLoad {
    [super viewDidLoad];

    NSDictionary *dict = @{@"Alabama":@[@"Alabama Area 1", @"Alabama Area 2", @"Alabama Area 3"], @"Georgia": @[@"Georgia Area 1", @"Georgia Area 2", @"Georgia Area 3"], @"Tennessee":@[@"Tennessee Area 1", @"Tennessee Area 2", @"Tennessee Area 3"], @"Colorado":@[@"Colorado Area 1", @"Colorado Area 2", @"Colorado Area 3"]};

    areas = dict[self.stateName];
}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return areas.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *simpleTableIdentifier = @"AreaCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    cell.textLabel.text = areas[indexPath.row];
    return cell;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    //push segue identifier 'showArrayDetail'
    if([segue.identifier isEqualToString:@"showAreaDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        ThirdTableViewController *destViewController = segue.destinationViewController;
        destViewController.areaName = areas[indexPath.row];
        destViewController.title = [NSString stringWithFormat:@"%@ Climbs", destViewController.areaName];
    }
}

OTHER TIPS

I think the problem is in your numberofrowsinsection method. At the very end after you check which array you are using you return zero. Comment out that line and see what happens.

EDIT #1

I was using area1 and area2 as examples, you can have as many as you want, if you have over 300 you might want to use a switch case but the if statement should look like this.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int i = 0;  // or something else

if ([_areaName isEqualToString:@"Alabama Area 1"])
     {
         i = [_oneArray count];
     }else if ([_areaName isEqualToString:@"Alabama Area 2"])
     {
         i = [_twoArray count];
     }

// Return the number of rows in the section.
return i;

}

This will allow you to have anything be i and then return that number. Let me know if it works.

EDIT #2

When I was trying out your code, I did notice that areas in vc #2 was never declared. I think you wanted to say the specific area. So I changed the segue to this..

if ([_stateName isEqualToString:@"Alabama"])
    {

        dvc.areaName = [alabama objectAtIndex:indexPath.row];
    }
    else if ([_stateName isEqualToString:@"Georgia"])
    {

        dvc.areaName = [georgia objectAtIndex:indexPath.row];
    }else if ([_stateName isEqualToString:@"Tennessee"])
    {

        dvc.areaName = [tenessee objectAtIndex:indexPath.row];
    }else if ([_stateName isEqualToString:@"Colorado"])
    {

        dvc.areaName = [colorado objectAtIndex:indexPath.row];
    }

this just replaces where you had dvc.areaName = [areas objectAtIndex:indexPath.row]; I know @rdelmar said the same thing, but I wanted to finish where we left off and help you with the code. One note, you will need other areas in the third tableview, because currently the code just has the two places in Alabama.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top