NSMutableArray Not Adding Objects - xcode

I have a main view controller that consists of 1 button that when tapped, pushes a detail view controller and another button that simply launches a modal view controller that has a table. This detail view controller has a button that when tapped should add a new object to the array that was loaded by the table in the modal view controller.
Problem is, that add a new object button doesn't add to the NSMutableArray.
When I put a button in the main view and assigned the same method of adding objects to the NSMutableArray, it works. It just doesn't work when the button is placed on another view controller presented either via Navigation Controller and Modal View.
Here's my code when the button is pressed in the detail view controller:
- (IBAction)confirmBtnPressed
{
// Gets the current time and formats it
NSDate *timeNow = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:#"hh:mm a"];
// Gets the current date and formats it
NSDate *dateNow = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd, yyyy"];
NSString *currentTime = [timeFormatter stringFromDate:timeNow];
NSString *currentDate = [dateFormatter stringFromDate:dateNow];
NSString *timestamp = currentTime;
NSString *date = currentDate;
// This is where values gets saved
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:timestamp forKey:kTimeStampText];
[defaults setObject:date forKey:kDateText];
[defaults synchronize];
NSString *timeToday = [defaults objectForKey:kTimeStampText];
NSString *dateToday = [defaults objectForKey:kDateText];
tableVC.tableDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:timeToday, #"Time", dateToday, #"Date", nil];
[tableVC.tableArray addObject:tableVC.tableDict];
[tableVC.table reloadData];
}
Here's my code in the main view controller when the button to load the table modally is pressed:
// Table loaded
- (IBAction)viewHistoryPressed:(id)sender
{
if (!self.historyViewController)
{
self.historyViewController = [[HistoryViewController alloc] initWithNibName:#"HistoryViewController" bundle:nil];
}
[self presentModalViewController:historyViewController animated:YES];
}
Here's my viewDidLoad in my table view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *time = [defaults objectForKey:kTimeStampText];
NSString *date = [defaults objectForKey:kDateText];
tableDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:time, #"Time", date, #"Date", nil];
tableArray = [[NSMutableArray alloc] initWithObjects:tableDict, nil];
}
Screenshot of the main view:
detail view:
table view:

Try initializing your NSMutableArray with:
NSMutableArray *array = [NSMutableArray array];
Now you are open to adding entries.
Let me know if this works for you.

in viewDidLoad method... please use self.tableDict and self.tableArray while allocating them. 'self' calls the getter and setter methods so it is imp.

Related

How to Load View Controllers At the Beginning of the App?

I have a Tab View Controller as my root controller in an App which consists of 3 tabs let's call them View A, View B, View C.
I want to load these tabs as soon as my app starts, I think it can be done within didFinishLaunchingWithOptions function but I'm not exactly sure, does anyone know how to do it?
Thanks
For these kinds of purposes I used this approach:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
UITabBarController *tabBarController = [[UITabBarController alloc] init];
rootView = [[SGMenuViewController alloc] init];
UIViewController *tab1VC = [[UIViewController alloc] init];
UIViewController *tab2VC = [[UIViewController alloc] init];
UIViewController *tab3VC = [[UIViewController alloc] init];
UIViewController *tab4VC = [[UIViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:rootView];
UINavigationController *secondNavController = [[UINavigationController alloc] initWithRootViewController:tab3VC];
NSArray* controllers = [NSArray arrayWithObjects:navController, tab2VC, secondNavController, tab4VC, nil];
tabBarController.viewControllers = controllers;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
You basically create a UITabBarController and you put all your view there. You create a UINavigationController if you need to push/pop views in the selected tab. In the example above only the 1st and the 3rd tab have UINavigationController and so I can use self.navigationController pushViewController: on them.

Xcode: Remove objects from NSMutableArray based on NSDictionary

I am new to tableViews and dictionaries and i have a problem!
In ViewDidLoad i am initializing many MutableArrays and i am adding data using NSDictionary. Example:
- (void)viewDidLoad {
nomosXiou=[[NSMutableArray alloc] init];
[nomosXiou addObject:[[NSDictionary alloc] initWithObjectsAndKeys:#"Mary",#"name",#"USA",#"country", nil]];
[nomosXiou addObject:[[NSDictionary alloc] initWithObjectsAndKeys:#"Peter",#"name",#"Germany",#"country", nil]];
[super viewDidLoad];
// Do any additional setup after loading the view.}
In a previous ViewController the user selects a Country. Based on that selection, how could i remove from my arrays all the other entries???
Thanks in advance...
First note that your code fragment has an error. It should read:
NSMutableArray *nomosXiou= [[NSMutableArray alloc] init];
There are a number of ways to do what you want, but the most straightforward is probably the following:
NSString *countryName; // You picked this in another view controller
NSMutableArray *newNomosXiou= [[NSMutableArray alloc] init];
for (NSDictionary *entry in nomosXiou) {
if ([[entry objectForKey:#"country"] isEqualToString:countryName])
[newNomosXiou addObject:entry];
}
When this is done newNomosXiou will contain only the entries in nomosXiou that are from the country set in countryName.
Something like this will do the job:
NSMutableArray *nomosXiou = [[NSMutableArray alloc] init];
NSString *country = #"Germany"; // This is what you got from previous controller
// Some test data. Here we will eventually keep only countries == Germany
[nomosXiou addObject:[[NSDictionary alloc] initWithObjectsAndKeys:#"Mary",#"name",#"USA",#"country", nil]];
[nomosXiou addObject:[[NSDictionary alloc] initWithObjectsAndKeys:#"Peter",#"name",#"Germany",#"country", nil]];
[nomosXiou addObject:[[NSDictionary alloc] initWithObjectsAndKeys:#"George",#"name",#"Germany",#"country", nil]];
// Here we'll keep track of all the objects passing our test
// i.e. they are not equal to our 'country' string
NSIndexSet *indexset = [nomosXiou indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop){
return (BOOL)![[obj valueForKey:#"country"] isEqualToString:country];
}];
// Finally we remove the objects from our array
[nomosXiou removeObjectsAtIndexes:indexset];

How to Create UITableView with History of Button Clicks

I'm creating an app that should list the date and time when a button is clicked and put the list inside a UITableView. My idea is to get the date and timestamp every time the user taps the button and then save it in an array of dictionary objects of every time and date when the button was clicked. I'll also have another button that simply loads a modal view that displays the said UITableView with the list of the history of button clicks.
I was able to do it partially with my table getting populated with the number of dictionary entries inside the array. Problem is, it always end up with the same time and date for all of the entries.
Here's a screenshot of the table initially with one entry.
and this what happens when I tapped the button many times. It displays the updated time for all rows.
How can I display the history in the table and prevent it from being updated? I'm simply using NSUserDefaults also in saving the data.
Here's some code in my Button Clicked method:
- (IBAction)btnClicked:(id)sender
{
NSLog(#"Button pressed");
// Gets the current time and formats it
NSDate *timeNow = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:#"HH:mm a"];
// Gets the current date and formats it
NSDate *dateNow = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd, yyyy"];
NSString *currentTime = [timeFormatter stringFromDate:timeNow];
NSString *currentDate = [dateFormatter stringFromDate:dateNow];
NSString *timestamp = currentTime;
NSString *date = currentDate;
// This is where values gets saved
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:timestamp forKey:#"TimeStamp"];
[defaults setObject:date forKey:#"Date"];
[defaults synchronize];
NSString *time = [defaults objectForKey:#"TimeStamp"];
NSString *dateToday = [defaults objectForKey:#"Date"];
tableVC.tableDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:time, #"Time", dateToday, #"Date", nil];
[tableVC.tableArray addObject:tableVC.tableDict];
[tableVC.table reloadData];
}
This is my viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *time = [defaults objectForKey:kTimeStampText];
NSString *date = [defaults objectForKey:kDateText];
tableDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:time, #"Time", date, #"Date", nil];
tableArray = [[NSMutableArray alloc] initWithObjects:tableDict, nil];
}
This is my table methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (customCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell"
owner:self
options:nil];
for (id oneObject in nib) if ([oneObject isKindOfClass:[CustomCell class]])
customCell = (CustomCell *)oneObject;
}
customCell.dateLbl.text = [tableDict objectForKey:#"Date"];
customCell.timeLbl.text = [tableDict objectForKey:#"Time"];
return customCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 74;
}
Ok I think I found your problem, you are accessing the same date for each table row.
customCell.dateLbl.text = [tableDict objectForKey:#"Date"];
customCell.timeLbl.text = [tableDict objectForKey:#"Time"];
Is incorrect
NSDictionarry *dict = [tableArray objectAtIndex:[indexPath row]];
customCell.dateLbl.text = [dict objectForKey:#"Date"];
customCell.timeLbl.text = [dict objectForKey:#"Time"];
Now that should loop through it nicely and print all dates.
The problem with the code you had was that the row for index path method gets called for each row in the tableview, ie it is like a loop, so you assign each cells properties on it's own, hope this makes sense.

Init a UInavigationbar

I am having trouble in making a tableview with navigation bar or controller on top.
I have this piece of code,
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *addNavCon = [[UINavigationController alloc]initWithNibName:#"Welcome" bundle:nil];
self.navigationItem.rightBarButtonItem = self.addButtonItem;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[self createEditableCopyOfDatabaseIfNeeded];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
NSString *documentDirectory = [self applicationDocumentsDirectory];
NSString *path = [documentDirectory stringByAppendingPathComponent:#"notebook.plist"];
NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.Notes = tmpArray;
[tmpArray release];
}
However, the navigation bar never show up, while the table is doing fine. May i know what's the problem with the code?
Many thanks
You have created an instance of UINavigationController but never added it to anything. You need to add it to the current hierarchy or it will not appear.
If you wish to add the navController to the entire app, then you should do this in the App Delegate by
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
UIViewController *rootController = [[MyRootViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:rootController];
[rootController release];
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
}

Can't setViewControllers in my UITabBarController

I can't get setViewControllers to set the view controllers for my UITabBarController.
In the implementation for my UITabBarController subclass, I have:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"Test";
self.navigationItem.backBarButtonItem.title = #"To Test";
NSMutableArray *aViewControllersArray = [[NSMutableArray alloc] initWithCapacity:2];
UINavigationController* aNavigationController;
aNavigationController = [UIViewControllerOne alloc];
[aViewControllersArray addObject:aNavigationController];
[aNavigationController release];
aNavigationController = [UIViewControllerTwo alloc];
[aViewControllersArray addObject:aNavigationController];
[aNavigationController release];
[self setViewControllers:aViewControllersArray animated:TRUE];
[aViewControllersArray release];
}
The aViewControllersArray has the two UIViewControllers, but the viewControllers property of the UITabBarController is nil.
What am I doing wrong?
Figured it out:
In creating my UITabBarController I had been doing
[MyUITabBarController alloc]
rather than
[[MyUITabBarController alloc] init]
Adding init saved the day.

Resources