Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

igorland

macrumors newbie
Original poster
Mar 4, 2014
24
0
I have a ViewController where I enter a key through a textBox. The entered key pulls out all available records from a database where the same key is found. The list of the records forms NSMutableArray that I pass to UITableViewController, where the user can pick one. Then on the initial ViewController, this value should be selected.

Two issues:

1. Is there a way to open the TableViewController as modal and programmatically (not with the StoryBoard)? I have some "if" statements there that should control whether the TableViewController opens.

2. I cannot pass the array from the ViewController to TableViewController. Since I have no answer for question 1, I am doing it using another button (test). NSLog in UITableViewController tells me that the array there is null.

UIViewController.h:
Code:
@interface IGAViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
NSString *navigationPoint;
NSMutableArray *navigationList; // List of all navigation points with the same name
}

@property (nonatomic,retain, getter=passNavigationList) NSMutableArray *navigationList;
@property (nonatomic,retain) NSString *navigationPoint;

// Return navigation list
-(NSMutableArray *) passNavigationList;

UIViewController.mm
Code:
@implementation IGAViewController

@synthesize navigationPoint, navigationList;

// Return navigation list
-(NSMutableArray *) passNavigationList {
    return navigationList;
    NSLog(@"NAVIGATION LIST AGAIN: %@", navigationList);
}

// Add a Navigation Point
-(IBAction) addIcaoNavigation:(id)sender {

    // Setting up the path to the navigation points database
    pathNav = [[NSBundle mainBundle] pathForResource:@"navdata_nav"
                                              ofType:@"txt"];
    
    // Text entered in the textfield is assigned as the Navigation Point
    navigationPoint = txtNavIcao.text;
    
     // If the Departure airport is not determined, this will give an error. Determine Departure first.
    if ([txtDepIcao.text isEqual:@""] || portDeparture == nil) {
        // Pop-up message that the airport was not found
        UIAlertView* portNotFoundMsg;
        portNotFoundMsg = [[UIAlertView alloc] initWithTitle:@"No Departure airport"
                                                     message:@"Select the Departure airport first"
                                                    delegate:self
                                           cancelButtonTitle:@"OK"
                                           otherButtonTitles:nil, nil];
        [portNotFoundMsg show];
    }
    
    else {
        
// Create an object for the Navigation Points and getting data
        IGDNavigation* navObj = [[IGDNavigation alloc] initWithName: navigationPoint navdataPath: pathNav];
        
// Creating a list of all points with the same code sorted by the distance from departure
navigationList = [navObj navDataWithPreviousLatitude:depLatitude PreviousLongitude:depLongitude]; 
        
NSLog(@"NAVIGATION LIST: %@", navigationList);
        
// Open the UITableViewController
// THIS IS WHERE HELP FOR Q1 IS NEEDED

 
 NSLog(@"NAVIGATION POINT: %@", navigationPoint);

UITableViewController.h
Code:
@interface IGANavListTableViewController : UITableViewController    {
    NSString *navPoint;
    NSMutableArray *listOfNavPoints;
}

@property (nonatomic,strong) NSMutableArray *listOfNavPoints;
@property (nonatomic,strong) NSString *navPoint;

UITableViewController.mm
Code:
@implementation IGANavListTableViewController

@synthesize listOfNavPoints, navPoint;

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

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Pass the list of Navigation Points
    IGAViewController *mainObj = [[IGAViewController alloc] init];
    
    
// listOfNavPoints = [[NSMutableArray alloc] initWithObjects:@"111",@"222",@"333", nil]; // THIS WORKS!
    
listOfNavPoints = [mainObj passNavigationList]; // THIS DOES NOT WORK!
    
    // THIS IS JUST TO CHECK IF PASSING WORKS
    navPoint = mainObj.navigationPoint;
    NSLog(@"VIEW DID LOAD: %@", navPoint);
}

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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [listOfNavPoints count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    
    //UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    
    // Configure the cell...
    if (cell==nil)  {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
    }
    
    cell.textLabel.text = [listOfNavPoints objectAtIndex:indexPath.row];
    
    return cell;
}

In the end, I have:
Code:
NAVIGATION LIST: (
    "NDB|GIG|GERING|41.944356|-103.683|341 Khz|639 nm",
    "NDB|GIG|GINGIN|-31.459722|115.865556|372 Khz|8275 nm"
)

NAVLIST DID LOAD: (null)

I have been fighting this dilemma for a week already, although it should be a simple thing to do. I would really appreciate people's help!
 

mjohnson1212

macrumors member
Nov 15, 2007
92
11
presentViewController will show a view controller modally.

When you create your subclass of UITableViewController just create a property to pass in the data.
 

igorland

macrumors newbie
Original poster
Mar 4, 2014
24
0
Hi, guys. Thank you for trying to help. I am still learning and therefore some of the stuff that is obvious to you is not clear to me. So, please bear with me, :eek:

So, after reading and re-reading tens of articles and forum messages, I still do not see why it is not working. I changed the code. Now it is as follows:

IGAViewController.h
Code:
#import <UIKit/UIKit.h>
#import "IGDNavigation.h"
#import "IGANavListTableViewController.h"

@interface IGAViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
    // Navigation points
    NSString *pathNav;
    NSString *navigationPoint;
    NSMutableArray *navigationList; // List of all navigation points with the same name
}

@property (nonatomic,retain) NSString *navigationPoint;

@property (nonatomic,retain, getter=passNavigationList) NSMutableArray *navigationList;

@property (nonatomic,retain) IBOutlet UITextField *txtNavIcao;

-(IBAction) addIcaoNavigation:(id)sender;
-(IBAction) test:(id)sender;

@end

IGAViewController.mm
Code:
#import "IGAViewController.h"

@interface IGAViewController ()

@property (weak, nonatomic) IBOutlet UIButton *testButton;

@end

@implementation IGAViewController

@synthesize navigationPoint, navigationList;


// Add a Navigation Point
-(IBAction) addIcaoNavigation:(id)sender {

    // Setting up the path to the navigation points database
    pathNav = [[NSBundle mainBundle] pathForResource:@"navdata_nav"
                                              ofType:@"txt"];
    
    // Text entered in the textfield is assigned as the Navigation Point
    navigationPoint = txtNavIcao.text;
    
     // If the Departure airport is not determined, this will give an error. Determine Departure first.
    if ([txtDepIcao.text isEqual:@""] || portDeparture == nil) {
        // Pop-up message that the airport was not found
        UIAlertView* portNotFoundMsg;
        portNotFoundMsg = [[UIAlertView alloc] initWithTitle:@"No Departure airport"
                                                     message:@"Select the Departure airport first"
                                                    delegate:self
                                           cancelButtonTitle:@"OK"
                                           otherButtonTitles:nil, nil];
        [portNotFoundMsg show];
    }
    
    else {
        
        // Create an object for the Navigation Points
        IGDNavigation* navObj = [[IGDNavigation alloc] initWithName: navigationPoint navdataPath: pathNav];
        
        // Creating a list of all points with the same code sorted by the distance from departure
        navigationList = [navObj navDataWithPreviousLatitude:depLatitude PreviousLongitude:depLongitude];
        
        NSLog(@"NAVIGATION LIST: %@", navigationList);

    }
}


-(IBAction)test:(id)sender {
    IGANavListTableViewController *listObj = [[IGANavListTableViewController alloc]init];
    
    [listObj loadNavData:navigationList];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

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

@end

IGANavListTableViewController.h
Code:
#import <UIKit/UIKit.h>

@interface IGANavListTableViewController : UITableViewController    {
    NSString *navPoint;
}

-(void) loadNavData: (NSMutableArray *) nadData;
-(IBAction)cancel:(id)sender;

@end

IGANavListTableViewController.mm
Code:
#import "IGANavListTableViewController.h"
#import "IGAViewController.h"
#import "IGDNavigation.h"

@interface IGANavListTableViewController ()

// Declare the mutable array with a list of nav points
@property NSMutableArray *listOfNavPoints;

@end

@implementation IGANavListTableViewController


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

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.listOfNavPoints = [[NSMutableArray alloc] init];

    // Here _listOfNavPoints is initialized but empty. But it is not empty in the loadNavData method! Do I somehow need to implement that method here again?
    NSLog(@"NAVLIST DID LOAD: %@", _listOfNavPoints);
}


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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [_listOfNavPoints count];
}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"ListPrototypeCell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
     
    cell.textLabel.text = [_listOfNavPoints objectAtIndex:indexPath.row];
    
    return cell;
}

// Passing the value to the original view with the selected navigation point

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  {
    NSLog(@"DID SELECT ROW AT INDEX PATH");
    NSLog(@"Row: %d",indexPath.row);
    // TO DO
}


// This button closes the table with Navigation Points
-(IBAction)cancel:(id)sender    {
    [self dismissViewControllerAnimated:YES completion:nil];
}

// This method works!!! returns the array
-(void) loadNavData: (NSMutableArray *) navData {
    _listOfNavPoints = navData;
    
    NSLog(@"_LISTOFNAVPOINTS: %@",_listOfNavPoints);
}

@end

By the way, I tried to implement the following in the IGAViewController:
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"ListPrototypeCell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
     
    cell.textLabel.text = [navigationList objectAtIndex:indexPath.row];
    
    return cell;
}

Still does not work. Cannot believe that it is taking so long! Million thanks, guys!
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
Code:
-(IBAction)test:(id)sender {
    IGANavListTableViewController *listObj = [[IGANavListTableViewController alloc]init];
    
    [listObj loadNavData:navigationList];
}

In the above code, I see you've alloc/init'd your IGANavListTableViewController, but I can't see where you actually present the view for it.
 

igorland

macrumors newbie
Original poster
Mar 4, 2014
24
0
dejo. Thanks a lot for bearing with me!

In my -(IBAction)test:(id)sender method, I implement the following method in UITableViewController:

Code:
// This method works!!! returns the array
-(void) loadNavData: (NSMutableArray *) navData {
    _listOfNavPoints = navData;
    
    NSLog(@"_LISTOFNAVPOINTS: %@",_listOfNavPoints);
}

This code works perfectly well and returns the same array as in navigationList in UIViewController. Now, I assume that _listOfNavPoints is already set, however, when I implement this method:

Code:
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.listOfNavPoints = [[NSMutableArray alloc] init];

    // Here _listOfNavPoints is initialized but empty. But it is not empty in the loadNavData method! Do I somehow need to implement that method here again?
    NSLog(@"NAVLIST DID LOAD: %@", _listOfNavPoints);
}

_listOfNavPoints is empty!

I now tried this:

Code:
@interface IGANavListTableViewController ()

// Declare the mutable array with a list of nav points
@property NSMutableArray *listOfNavPoints;
@property NSMutableArray *arrayTemp;

@end

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.listOfNavPoints = [[NSMutableArray alloc] init];
    
    [_listOfNavPoints addObject:_arrayTemp];

    NSLog(@"ARRAYTEMP: %@",_arrayTemp);
    NSLog(@"NAVLIST DID LOAD: %@", _listOfNavPoints);
}

...

-(void)loadNavData: (NSMutableArray *) navData {
    
    _arrayTemp = [[NSMutableArray alloc] init];
    _arrayTemp = navData;
    
    NSLog(@"_LIST OF NAVIGATION POINTS IN LOADNAVDATA: %@", _arrayTemp);

}

_LIST OF NAVIGATION POINTS IN LOADNAVDATA: shows the right array

but the application crashes, because ARRAYTEM: _tempArray is nil. But WHY?????
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
Code:
self.listOfNavPoints = [[NSMutableArray alloc] init];

What do you think this line of code does if listOfNavPoints already contains values? Do you think it leaves it alone?

Hi, guys. Thank you for trying to help. I am still learning and therefore some of the stuff that is obvious to you is not clear to me. So, please bear with me, :eek:

Given that, please tell us what resources you're using to learn the fundamentals of iOS/Objective-C programming. Be as specific as possible. Your improper use of underscore-starting instance-variables, like _listOfNavPoints (they should only be referenced in init-type methods) show that you don't seem to have a solid grasp of the basics.
 

igorland

macrumors newbie
Original poster
Mar 4, 2014
24
0
I have included several options of codes here and it looks messy now. In some cases, they are mutually exclusive, and therefore cause the above questions. Sorry if this is the case.

Given that, please tell us what resources you're using to learn the fundamentals of iOS/Objective-C programming. Be as specific as possible. Your improper use of underscore-starting instance-variables, like _listOfNavPoints (they should only be referenced in init-type methods) show that you don't seem to have a solid grasp of the basics.

Xcode inserts it for me otherwise producing errors. I agree, it should have been self.listOfNavPoints.

I'd rather not include the resources in this thread. I usually try to be right to the point and avoid straying from the topic to the extent possible.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.