ecatalano
ecatalano

Reputation: 687

Populating a UITableView within a UIViewController and changing data source with UISegmentedControl

I am trying to populate a UITableView that I put inside a UIViewController, underneath a UISegmentedControl, which is depicted in the picture:

enter image description here

Upon pressing any of the segments, I want the UITableView to be repopulated with a different set of data. Here is my relevant code:

@interface OTValuesViewController ()

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentControl;

@end

@implementation OTValuesViewController


- (IBAction)segmentValueChanged:(id)sender {
    UISegmentedControl *segment = self.segmentControl;
    UINavigationItem *navItem = self.navigationItem;
    UIBarButtonItem *addButton = navItem.rightBarButtonItem;
    switch (segment.selectedSegmentIndex) {
        case 0:
            addButton.action = @selector(addNewVision:);
            [self.tableView reloadData];
            break;
        case 1:
            addButton.action = @selector(addNewPurpose:);
            [self.tableView reloadData];
            break;
        case 2:
            addButton.action = @selector(addNewPlan:);
            [self.tableView reloadData];
            break;
        default:
            [self.tableView reloadData];
            break;

    }
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UISegmentedControl *segment = self.segmentControl;
    UITableViewCell *cell = [tableView     dequeueReusableCellWithIdentifier:@"OTValuesTableViewCell" forIndexPath:indexPath];

    NSArray *visions = [[OTVisionStore sharedStore] allVisions];
    NSArray *purposes = [[OTPurposeStore sharedStore] allPurposes];
    NSArray *plans = [[OTPlanStore sharedStore]allPlans];

    OTVision *vision = [visions objectAtIndex:indexPath.row];
    OTVision *purpose = [purposes objectAtIndex:indexPath.row];
    OTVision *plan = [plans objectAtIndex:indexPath.row];

    NSString *textLabel = [vision description];

    if (segment.selectedSegmentIndex==0) {
        textLabel = [vision description];
        cell.textLabel.text = textLabel;
    }
    else if (segment.selectedSegmentIndex==1) {
        textLabel = [purpose description];
        cell.textLabel.text = textLabel;
    }
    else{
        textLabel = [plan description];
        cell.textLabel.text = textLabel;
    }
    return cell;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    UISegmentedControl *segment = self.segmentControl;
    if(segment.selectedSegmentIndex==0) {
        return [[[OTVisionStore sharedStore]allVisions]count];
    }
    else if (segment.selectedSegmentIndex==1) {
        return [[[OTPurposeStore sharedStore]allPurposes]count];
    }
    else{
        return [[[OTPlanStore sharedStore]allPlans]count];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.tableView.dataSource = self;
    self.tableView.delegate = self;

    self.title=@"Mission Statement";

    UINavigationItem *navItem = self.navigationItem;

    UIBarButtonItem *rbbi = [[UIBarButtonItem alloc]     initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
                                                                     target:self
                                                                     action:@selector(addNewVision:)];
    navItem.rightBarButtonItem = rbbi;
}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.tableView reloadData];
}

My issue is: when I build and run the project, everything is fine -- the cells are populated in my default tab (vision). When I click a UISegmentedControl button, I get the error:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

If I remove:

self.tableView.dataSource = self;
self.tableView.delegate = self;

from my viewDidLoad, this error does not occur (though, the UITableView obviously doesn't get populated.) This leads me to believe that the error is derived from my populating the cells based on the UISegmentedController's selected segment, however, I do not know what is specifically causing it.

Any help would be greatly appreciated!

Upvotes: 0

Views: 182

Answers (1)

rmaddy
rmaddy

Reputation: 318804

The problem is in your cellForRowAtIndexPath method. You try to use the current index path for all of your arrays, not just the applicable array. Try something like this:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UISegmentedControl *segment = self.segmentControl;
    UITableViewCell *cell = [tableView     dequeueReusableCellWithIdentifier:@"OTValuesTableViewCell" forIndexPath:indexPath];

    if (segment.selectedSegmentIndex==0) {
        NSArray *visions = [[OTVisionStore sharedStore] allVisions];
        OTVision *vision = [visions objectAtIndex:indexPath.row];
        NSString *textLabel = [vision description];
        cell.textLabel.text = textLabel;
    }
    else if (segment.selectedSegmentIndex==1) {
        NSArray *purposes = [[OTPurposeStore sharedStore] allPurposes];
        OTVision *purpose = [purposes objectAtIndex:indexPath.row];
        NSString *textLabel = [purpose description];
        cell.textLabel.text = textLabel;
    }
    else{
        NSArray *plans = [[OTPlanStore sharedStore]allPlans];
        OTVision *plan = [plans objectAtIndex:indexPath.row];
        NSString *textLabel = [plan description];
        cell.textLabel.text = textLabel;
    }

    return cell;
}

Upvotes: 1

Related Questions