0

I'm building a sign-in app. It has two table views. One lists people who have visited before (existingNames), and one lists the current people signed in (names).

At certain points in my code the only mutable array that does not crash the program when accessed is names.

names and existingNames seems to somehow be reversed as well. When I try to remove from names, the program crashes. When I remove from existingNames, the changes are reflected in tableView2, but tableView2 is supposed to be associated with names.

In the app's current state everything is "working" except for accessing any company arrays. I put quotes around working because of the names and existingNames being used backwards.

Any insight into what might be causing the problem would be much appreciated!

.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>{
    UITableView *tableView;
}

@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *companyField;
@property (nonatomic, retain) NSMutableArray *names;
@property (nonatomic, retain) NSMutableArray *companies;
@property (nonatomic, retain) NSMutableArray *existingNames;
@property (nonatomic, retain) NSMutableArray *existingCompanies;

- (IBAction)add:(id)sender;
- (IBAction)addExisting:(id)sender;
- (IBAction)remove:(id)sender;
- (IBAction)submit:(id)sender;

@property (strong, nonatomic) IBOutlet UITableView *tableView1;
@property (weak, nonatomic) IBOutlet UITableView *tableView2;

@end

.m:

#import "ViewController.h"
#import <MessageUI/MessageUI.h>

@interface ViewController () <MFMailComposeViewControllerDelegate>

@end

@implementation ViewController

@synthesize nameField;
@synthesize companyField;
@synthesize names;
@synthesize companies;
@synthesize existingNames;
@synthesize existingCompanies;
@synthesize tableView1 = _tableView1;
@synthesize tableView2 = _tableView2;

int rowNumber1;
int rowNumber2;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.names = [[NSMutableArray alloc] init];
    self.companies = [[NSMutableArray alloc] init];
    self.existingNames = [[NSMutableArray alloc] init];
    self.existingCompanies = [[NSMutableArray alloc] init];
    // Do any additional setup after loading the view, typically from a nib.
}

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.tableView1){
        return [existingNames count];
    }
    else if (tableView == self.tableView2){
        return [names count];
    }
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"SimpleTableItem";
    UITableViewCell *cell;

    if (tableView == self.tableView1){
        cell = [_tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    }
    else if (tableView == self.tableView2){
        cell = [_tableView2 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    }

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }

    if (tableView == self.tableView1){
        cell.textLabel.text = [existingNames objectAtIndex:indexPath.row];
    }
    else if (tableView == self.tableView2){
        cell.textLabel.text = [names objectAtIndex:indexPath.row];
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if (tableView == self.tableView1){
        rowNumber1 = indexPath.row;
    }
    else if (tableView == self.tableView2){
        rowNumber2 = indexPath.row;
    }
}

- (IBAction)add:(id)sender {
    BOOL exists = [existingNames containsObject:nameField.text];

    if(exists == FALSE){
        [names addObject:nameField.text];
        [companies addObject:companyField.text];
        [existingNames addObject:nameField.text];
        [existingCompanies addObject:companyField.text];
    }
    else{
        [names addObject:nameField.text];
        [companies addObject:companyField.text];
    }

    [_tableView1 reloadData];
    [_tableView2 reloadData];

    nameField.text=@"";
    companyField.text=@"";
}

- (IBAction)addExisting:(id)sender {
    [existingNames addObject:[names objectAtIndex:rowNumber1]];
    //[companies addObject:[existingCompanies objectAtIndex:rowNumber]];

    [_tableView2 reloadData];
}

- (IBAction)remove:(id)sender {
    [existingNames removeObjectAtIndex:rowNumber2];
    [existingCompanies removeObjectAtIndex:rowNumber2];

    [_tableView2 reloadData];
}

@end

1 Answer 1

1

The following methods are part of the UITableViewDataSource and UITableViewDelegate protocols

tableView:numberOfRowsInSection:
tableView:cellForRowAtIndexPath:
tableView:didSelectRowAtIndexPath:

and will be called by your table view assuming you've property assigned the table view's delegate and dataSource properties. These methods, however,

tableView2:numberOfRowsInSection:
tableView2:cellForRowAtIndexPath:
tableView2:didSelectRowAtIndexPath:

are not part of the protocol and won't ever get called by the table view. It looks like you may be confusing your property names, e.g. tableView, with with the protocol method names, e.g. tableView:numberOfRowsInSection:. What you need to do is:

  1. If you haven't already done so, set your view controller as the delegate and dataSource for both your tableView and tableView2.
  2. In each of the data source and delegate methods that you need to implement, handle the cases for both tables.

For example, your tableView:numberOfRowsInSection: method would look like:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.tableView) {
        return [existingNames count];
    }

    else if (tableView == self.tableView2) {
        return [names count];
    }

    return 0;
}
9
  • I have set the datasource and delegate for both table views already. Thanks in your help in understanding with the tableview docs, they're really a lot to take in! I'll work on it and let you know if anything improves. Commented Jun 13, 2013 at 16:18
  • I've been at this for awhile now and I've got the program running, only now the table views are not being populated. I'm posting my new code. I'm assuming it has something to do with the tableview methods. I am receiving a warning every time I reference tableView inside those methods "local declaration of tableView hides instance variable". I have tried other methods to remove this warning, but nothing else has worked. Commented Jun 17, 2013 at 17:57
  • Ahh, I got rid of it by adding _ to the method declaration (i.e. - (NSInteger)tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)section). My table views are currently still not being populated though. Any suggestions? Commented Jun 17, 2013 at 18:10
  • I'm assuming it now has to do with when I call tableView and _tableView in these methods. I'm having trouble understanding when to use which. Commented Jun 17, 2013 at 18:22
  • In your interface, you've defined a variable "tableView" and a property "tableView". But in your implementation, you're synthesizing and referencing "tableView1" It seems you're not being consistent with what you're variables. I would suggest a) delete the "tableView" variable definition, b) rename the property from "tableView" to "tableView1", c) undo "adding _ to the method declaration", and d) see how things look. You can put log statements or breakpoints in your delegate methods to make sure they're getting called, verify your arrays, are populated, etc. Commented Jun 17, 2013 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.