Display dates for a year in a tableview - arrays

What I am trying to accomplish here is taking a tableView with a prototype cell, and display the dates in each cell for a year, or two years. I have gotten it to display todays date in the label by using the following code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate *dateNow = [NSDate date];
dateArray = [NSMutableArray arrayWithObjects:[dateFormatter stringFromDate:dateNow], nil];
It works to add one date (todays date) to the first cell. I can not figure out how to get it to add all days by an interval of 1. Any help?
I display the information in the array with this code:
static NSString *CellIdentifier = #"Cell";
Custom *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.dateLabel.text = [dateArray objectAtIndex:indexPath.row];

Here you go,
in the viewDidload,
dateArray = [[NSMutableArray alloc] init]; //dateArray is global
NSDate *thisDate, *nextDate;
thisDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
[dateArray addObject: [dateFormatter stringFromDate:thisDate]];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = 1;
for (int i = 0; i<365; i++) //Not considering leap years
{
nextDate = [gregorian dateByAddingComponents:components toDate:thisDate options:0];
[dateArray addObject:[dateFormatter stringFromDate:nextDate]];
thisDate = nextDate;
}
in the cellForRowAtIndexPath
cell.dateLabel.text = [dateArray objectAtIndex:indexPath.row];

You don't need to maintain an array of dates. If you want to display the nth row, you can just add n days to your start date and use that.
So you'd have your start date stored in an instance variable:
NSDate *_startDate;
To determine how many rows should be in the tableView, you have to figure out how many days are in that year (I'm going to assume you're only displaying one year):
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// get the calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// get the date that points to the first day of the first month of the year containing the start date
// note that we include the era, because some calendars have more than an "AD"/"BC" kind of era
NSDateComponents *yearStartComponents = [calendar components:(NSEraCalendarUnit | NSYearCalendarUnit) fromDate:_startDate];
[yearStartComponents setMonth:1];
[yearStartComponents setDay:1];
NSDate *startOfYear = [calendar dateFromComponents:yearStartComponents];
NSDateComponents *yearDiff = [[NSDateComponents alloc] init];
[yearDiff setYear:1];
// add one year to that date
NSDate *startOfNextYear = [calendar dateByAddingComponents:yearDiff toDate:startOfYear options:0];
// figure out how many days were between the two dates
NSDateComponents *dayDiff = [calendar components:NSDayCalendarUnit fromDate:startOfYear toDate:startOfNextYear options:0];
return [dayDiff day];
}
And then when you need the cell, you can just use the "row" of the indexPath as the number of days from the start date:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = ...;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *diff = [[NSDateComponents alloc] init];
[diff setDay:[indexPath row]];
NSDate *date = [calendar dateByAddingComponents:diff toDate:_startDate options:0];
NSLocale *locale = [NSLocale currentLocale];
NSString *formatted = [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterNoStyle locale:locale];
[[cell textLabel] setText:formatted];
return cell;
}
There are several nice things about this approach:
It works regardless of the length of the year. Whether the current year has 353, 355, 365, 366, or 384 days in the year, it'll work.
It works regardless of the current calendar. There's more than just the Gregorian calendar out there. NSCalendar supports the Gregorian, Buddhist, Chinese, Hebrew, Islamic, Islamic Civil, Japanese, Republic of China, Persian, Indian, and ISO8601 calendars.
You're not hard-coding a format string. By using the NSDateFormatterStyles, you'll be using the appropriate short-hand notation for a date, whether that's "5/12/12" or "5 Dec '12" or something entirely different.

Related

Convert a NSString to a NSDate

I have a NSString like this 05/09/2015 then I want to convert it into this format 2014-07-28 18:30:00 +0000
that second date was the one that I get from the system date. That date can be placed nicely on Tapku calender. but my string is the first one. I want to convert that 1st date just like as the date format that im getting from the system date. How can I do that.
Please help me. Thanks
NSString to NSDate
NSString *dateString = #"01-02-2010";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
// voila!
dateFromString = [dateFormatter dateFromString:dateString];
NSDateFormatter *otherFormatter = [[NSDateFormatter alloc] init];
[otherFormatter setDateFormat:#"yyyy-MM-dd"];
//[otherFormatter setTimeStyle:NSDateFormatterMediumStyle];
NSString *resultString = [otherFormatter stringFromDate:dateFromString];
NSLog(#"%#", resultString);
And then you can convert it back to an NSDate or keep as an NSString.
See this: Click Here

Detail View -> Objects -> NSMutableArray -> NSUserDefaults

I know this has been asked a million times, but I've been making a mess...
So basically what I'm trying to do is send an object from a details view to a favorites view with all of it's properties.
I've already got a button working to add a string [one property of the object] to favorites
button pressed code:
- (void)buttonPressed:(id) sender
{
NSMutableArray *favss = [[[NSUserDefaults standardUserDefaults] objectForKey:#"Favorite"]mutableCopy];
if(favss != nil)
{
NSLog(#"Array found. Contents: %#",favss);
}
else
{
favss = [[NSMutableArray alloc] initWithCapacity:0];
}
[favss addObject:self.word.head];
[[NSUserDefaults standardUserDefaults] setObject:favss forKey:#"Favorite"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"Number of items in my array is: %d", [favss count]);
}
my object is stored in it's own class:
#interface Words : NSObject {
NSString *head;
NSString *pro;
NSString *def;
}
#property(nonatomic, copy) NSString *head;
#property(nonatomic, copy) NSString *pro;
#property(nonatomic, copy) NSString *def;
when trying to run [favss addObject:self.word] the app obviously freaked out because objects can't be added to NSUserDefaults -- so I tried NSCoding but that turned my entire details view BLACK -- I've tried sending my three strings separately and that's fine but then they are all completely separated which kind of defeats the purpose -- and I somehow end up completely jacking up my arrays with all the different code I've been trying because now I keep getting this error:
Array found. Contents: <62706c69 73743030 d4010203 0405081d 1e542474 6f705824 6f626a65 63747358 24766572 73696f6e 59246172 63686976 6572d106 0754726f 6f748001 a6090a13 14151655 246e756c 6cd40b0c 0d0e0f10 11125468 65616456 24636c61 73735370 726f5364 65668002 80058003 8004615d f4536261 316f10cd 005b0070 00612075 2075005d 00202460 7c98003b 00208d34 002025b7 59277ea2 559c62a5 ff5e4e0a 58993002 24615207 54080020 25b77b54 662f7b54 5f978d77 ff0c5c31 60154e0d ff5e9898 30022462 63287740 002025b7 524d4e0d ff5e6751 ff0c540e 4e0dff5e 5e973002 24639644 7740003b 00208ddf 968f0020 25b7674e 5f3a83ab 5f977968 ff0cff5e 50127535 5f719662 76848001 738b5165 4e86573a 30022464 62767740 002025b7 624bff5e 95e8678b 5f805916 770b3002 24656cbf 7740003b 0020987a 77400020 25b74f60 ff5e6cb3 8fb95f80 4e0b8d70 ff0c4e0d 8fdc5c31 662f4e5d 773c6865 30022466 4eb28fd1 002025b7 4f607231 5a03513f ff0c5a03 513f5c31 ff5e4f60 30022467 72758fde 002025b7 90a35e74 5b506211 72385173 8fdb0020 201c725b 68da201d ff0c5f20 53d453d4 89c15230 62118fde 740690fd 4e0d7406 ff0c751f 6015628a 4ed6ff5e 50124e86 30022468 5df47ed3 002025b7 4f604ee5 4e3a628a 79d1957f ff5e5012 5c316709 597d5904 55e6003f 00202469 7167987e 003a0020 89c10020 201c5df4 5bb6201d 3002d217 18191c58 24636c61 73736573 5a24636c 6173736e 616d65a2 1a1b5557 6f726473 584e534f 626a6563 7455576f 72647312 000186a0 5f100f4e 534b6579 65644172 63686976 65720008 00110016 001f0028 00320035 003a003c 00430049 00520057 005e0062 00660068 006a006c 006e0071 00750212 02170220 022b022e 0234023d 02430248 00000000 00000201 00000000 0000001f 00000000 00000000 00000000 0000025a>
Basically, I just want my button to add the object that is being displayed in the details view into an array that is passed into NSUserDefaults to be displayed in a table view on the other side (which can then be selected to display the details of each object again)...and I know it's been asked a lot but...well, I can't even display my array at the moment...
If I understand you correctly, you need to store an array of objects (Word) that has 3 values (head, pro, def).
I suggest you store those three values in an NSDictionary:
head="xxx"
pro="yyy"
def="zzz"
and then you store this NSDictionary in an array, which is then stored in NSUserDefaults.
If you are adamant in storing your custom objects, you need to expand them a little.
The answer to this SO questions should get you there:
How to store custom objects in NSUserDefaults
i did it like this in the end:
- (void)apopbuttonPressed:(id) sender
{
NSMutableArray *myfavs = [[[NSUserDefaults standardUserDefaults] objectForKey:#"MyFavoritez"]mutableCopy];
if(myfavs != nil)
{
NSLog(#"Array found. Contents: %#",myfavs);
}
else
{
myfavs = [[NSMutableArray alloc] initWithCapacity:0];
}
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:#"MyFavoritez"];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
_myfavs = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
_myfavs = [[NSMutableArray alloc] init];
}
[_myfavs addObject:self.word];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:_myfavs] forKey:#"MyFavoritez"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"Number of items in my array is: %d", [_myfavs count]);
// [self performSegueWithIdentifier:#"passFavs" sender:favs];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"passFavs"]) {
FavViewController *con = segue.destinationViewController;
con.myFavsTwo = _myfavs; }
}
and
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
myFavsTwo = [NSKeyedUnarchiver unarchiveObjectWithData:[[[NSUserDefaults standardUserDefaults] objectForKey:#"MyFavoritez"] mutableCopy]];
[self.tableView reloadData];
NSLog(#"Number of items in my array is: %d", [myFavsTwo count]);
}
in case anyone else runs into similar issues

How to use NSMutableDictionary in an UIAlertView?

I am making a calorie counter and I have created an UIAlertView which gives me list of food items. I have made a NSMutableDictionary containing the food and the calories:
#implementation FoodDatabase
-(id)init
{
self = [super init];
if(self)
{
food= [[NSMutableDictionary alloc] init];
[food setObject:#"111" forKey:#"Rice"];
}
return self;
}
-(NSString *) foodList: (NSString *) foodItem
{
for(NSString *key in [food allKeys])
{
if([foodItem isEqual: key])
{
NSLog(#"%#",foodItem);
return [food objectForKey:foodItem];
}
}
}
#end
In another class, I have created an UIAlertView which gives a list of food items. This is the code snippet for the item Rice:
NSString *buttonTitle = [alertView buttonTitleAtIndex:buttonIndex];
if([buttonTitle isEqualToString:#"Rice"])
{
NSString *xyz = [foodData foodList: #"Rice"];
food_calorie = ([xyz floatValue]);
UIAlertView *rice_alert=[[UIAlertView alloc] initWithTitle:#"Enter quantity of rice consumed" message:#"100 gms = 111 calories" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[rice_alert addTextFieldWithValue:#"" label:#"Enter quantity in gms"];
RiceText = [rice_alert textFieldAtIndex:0];
RiceText.keyboardType = UIKeyboardTypeNumberPad;
RiceText.clearsOnBeginEditing = YES;
RiceText.clearButtonMode = UITextFieldViewModeWhileEditing;
RiceText.keyboardAppearance = UIKeyboardAppearanceAlert;
rice_alert.tag = RiceAlertView;
[rice_alert show];
[rice_alert release];
}
I calculate the total calories by using the value entered by the user in the _RiceText_ and the value of the _object_ returned for a specific key (in this case rice). But it seems not to be returning the value of the _object_ as the NSLog shows _(null)_ for the value of _xyz_. Where am I going wrong??
The whole error is that the object foodData isn't initialized properly. So, initialize it
A nice documentation - https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSObject_Class/Reference/Reference.html
& fetching data from NSmutableDictionary
https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/objectForKey:
Remember the key that you use to compare in dictionary should have same casing (capital - small) as defined earlier. e.g You store an object for key 'example' but you can not retrieve it using ''Example' or 'EXAMPLE'. You can only use 'example' as defined earlier. And
You don't need to get arrays of keys from dictionary & fast-enumerate it
You can just get the object using objectForKey: method. Good luck.

Local Notifications which update their content

Code:
-(void)viewWillDisappear:(BOOL)animated
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay: 3];
[components setMonth: 7];
[components setYear: 2012];
[components setHour: 21];
[components setMinute: 21];
[components setSecond: 30];
[calendar setTimeZone: [NSTimeZone defaultTimeZone]];
NSDate *dateToFire = [calendar dateFromComponents:components];
UILocalNotification *noti =[[UILocalNotification alloc] init];
noti.fireDate = dateToFire;
noti.repeatInterval = kCFCalendarUnitDay;
noti.soundName = #"chun.aiff";
noti.alertBody = [NSString stringWithFormat:#"Personal balance: %i", -PB];
[[UIApplication sharedApplication] scheduleLocalNotification:noti];
}
The flaw:
If I'm right, I'd say that once this local notification is "embedded" into the device's memory, it sticks with every local notification which has been created. I'm I right? If this is true, how can I manage this situation?
The notification alert is being repeated because you have used:
noti.repeatInterval = kCFCalendarUnitDay;
Your notification alert is scheduled only for the date you set using date to fire, but the alert is repeated on a day interval as you have set.
Set it to nil if you don't want it to repeat.
Hope it solves your problem.
:)

Populating an array into a TableView

In a tableView I have the following:
NSDictionary *cat = [category objectAtIndex:indexPath.row];
cell.textLabel.text = [cat valueForKey:#"reference"];
This populates the tableView with the content of the array from an XML file.
There is another array “data” that prints out the content to the debug console and I want to populate another view with this content. But I am having lot of trouble populating the next view with the data array.
NSLog(#"cellForRowAtIndexPath-- Reference:%#: Verse:%#", [cat valueForKey:#"reference"], [cat valueForKey:#"data"]);
The didSelectRowAtIndexPath method looks like this:
Verse *vvc = [[Verse alloc] initWithNibName:#"VerseView" bundle:nil]; vvc.verses = [[category objectAtIndex:indexPath.row] valueForKey:#"verse"];
[self.navigationController pushViewController:vvc animated:YES];
[vvc release];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
In the cellForRowAtIndexPath of the next view I have the following:
NSDictionary *cat = [verses objectAtIndex:indexPath.row];
cell.textLabel.text = [cat valueForKey:#"data"];
What I would like is to have the “data” in a textView.
I don’t know what’s wrong. Any help would be appreciated!

Resources