UITableView with sections - iphone

I have an app and in one view is a table. In the table I call the EventStore So It fills the table with your calendar events. I would like to have bars in the table like the ical app on the iphone so It breaks the days up with A bar the bar has the date (ex. March 25, 2011). Below is the code for the table
//eventsTable.h
#import <UIKit/UIKit.h>
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
#interface eventsTable : UIViewController <UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate,UIPopoverControllerDelegate,UINavigationControllerDelegate> {
IBOutlet UITableView *Table;
EKEventStore *eventStore;
EKEvent *event;
EKEventViewController *detailViewController;
EKCalendar *defaultCalendar;
NSMutableArray *eventsList;
}
-(IBAction) done;
- (NSArray *)fetchEventsForToday;
#property (nonatomic, retain)
IBOutlet UITableView *Table;
#property (nonatomic, retain) EKEventStore *eventStore;
#property (nonatomic, retain) EKCalendar *defaultCalendar;
#property (nonatomic, retain) NSMutableArray *eventsList;
#property (nonatomic, retain) EKEventViewController *detailViewController;
#end
//eventsTable.m
#import "eventsTable.h"
#implementation eventsTable
#synthesize eventsList, eventStore, defaultCalendar, detailViewController,Table;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Events List";
// Initialize an event store object with the init method. Initilize the array for events.
self.eventStore = [[EKEventStore alloc] init];
self.eventsList = [[NSMutableArray alloc] initWithArray:0];
// Get the default calendar from store.
self.defaultCalendar = [self.eventStore defaultCalendarForNewEvents];
// Create an Add button
// Fetch today's event on selected calendar and put them into the eventsList array
[self.eventsList addObjectsFromArray:[self fetchEventsForToday]];
[Table reloadData];
}
-(IBAction) done{
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark -
#pragma mark Table view data source
// Fetching events happening in the next 24 hours with a predicate, limiting to the default calendar
- (NSArray *)fetchEventsForToday {
NSDate *startDate1 = [NSDate date];
// endDate is 1 day = 60*60*24 seconds = 86400 seconds from startDate
NSDate *endDate1 = [NSDate distantFuture];
// Create the predicate. Pass it the default calendar.
NSArray *calendarArray = [NSArray arrayWithObject:defaultCalendar];
//NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate
// calendars:calendarArray];
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate1 endDate:endDate1 calendars:calendarArray];
// Fetch all events that match the predicate.
NSArray *events = [self.eventStore eventsMatchingPredicate:predicate];
events =
[events sortedArrayUsingSelector:
#selector(compareStartDateWithEvent:)];
self.eventsList = [NSMutableArray arrayWithArray:events];
[Table reloadData];
return events;
}
#pragma mark -
#pragma mark Table View
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return eventsList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *result = nil;
if ([tableView isEqual:self.Table] == YES){
static NSString *EventsCellIdentifier = #"Events";
/* We have the index path so let's get the corresponding
event from the array of events */
EKEvent *event1 = [self.eventsList
objectAtIndex:indexPath.row];
/* Try to get a reusable table cell */
result =
[tableView dequeueReusableCellWithIdentifier:EventsCellIdentifier];
if (result == nil){
result = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:EventsCellIdentifier] autorelease];
}
/* The title text of the cell will be the title of the event */
result.textLabel.text = event1.title;
result.textLabel.font = [UIFont boldSystemFontOfSize:16.0f];
result.detailTextLabel.font = [UIFont systemFontOfSize:12.0f];
/* Now let's format the date and the time of the event
and display it as the subtitle of the cell */
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components =
[calendar components:
NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit |
NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSSecondCalendarUnit
fromDate:event1.startDate];
NSDateComponents *components1 =
[calendar components:
NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit |
NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSSecondCalendarUnit
fromDate:event1.endDate];
if ([components hour] == 0 &&
[components minute] == 0 &&
[components second] == 0){
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];
NSDate *date = [calendar dateFromComponents: components1];
NSString *string = [NSDateFormatter localizedStringFromDate: date dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterNoStyle];
NSDate *date1 = [calendar dateFromComponents: components];
NSString *string1 = [NSDateFormatter localizedStringFromDate: date1 dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterNoStyle];
result.detailTextLabel.text =
[NSString stringWithFormat:#"All Day from %# - %#",string1,string,
(long)[components month],
(long)[components day],
(long)[components year],
(long)[components1 month],
(long)[components1 day],
(long)[components1 year]];
} else {
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];
NSDate *date = [calendar dateFromComponents: components1];
NSString *string = [NSDateFormatter localizedStringFromDate: date dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterShortStyle];
NSDate *date1 = [calendar dateFromComponents: components];
NSString *string1 = [NSDateFormatter localizedStringFromDate: date1 dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterShortStyle];
result.detailTextLabel.text =
[NSString stringWithFormat:#"%# - %#",string1,string,
(long)[components month],
(long)[components day],
(long)[components year],
(long)[components hour],
(long)[components minute],
(long)[components1 hour],
(long)[components1 minute]];
}
}
return(result);
[event release];
[eventsList release];
[eventStore release];
[result release];
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (void)viewDidUnload {
self.eventsList = nil;
self.view = nil;
self.Table = nil;
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
[Table release];
[eventStore release];
[eventsList release];
[defaultCalendar release];
[detailViewController release];
}
#end

You are going to have to split each day up into a separate section and implement the proper UITableViewDataSource protocols for section indexes: http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html
Here is a tutorial: http://www.iphonedevcentral.com/indexed-uitableview-tutorial/

If I understand your question correctly, you need to change the section titles with the date you want to display. You do this by implementing the (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section method.

You have a problem in your code despite the question. You must release the resources before the return.
return(result);
[event release];
[eventsList release];
[eventStore release];
[result release];

Related

UIDatePicker Scheduler Error

I have followed this tutorial
http://ios.biomsoft.com/2011/08/27/iphone-programming-tutorial-–-local-notifications/
I am able to run the app, however in order to run the app I have remove the following code in my appdelegate.m
You can see the error in the picture above.
Why do I receive the error and how do I fix the error?
Here is my code.
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {
IBOutlet UITableView *tableview;
IBOutlet UIDatePicker *datePicker;
IBOutlet UITextField *eventText;
}
#property (nonatomic, retain) IBOutlet UITableView *tableview;
#property (nonatomic, retain) IBOutlet UIDatePicker *datePicker;
#property (nonatomic, retain) IBOutlet UITextField *eventText;
- (IBAction) scheduleAlarm:(id) sender;
#end
.m
#implementation ViewController
#synthesize datePicker,tableview, eventText;
- (IBAction) scheduleAlarm:(id) sender {
[eventText resignFirstResponder];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
// Get the current date
NSDate *pickerDate = [self.datePicker date];
// Break the date up into components
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit |
NSMonthCalendarUnit | NSDayCalendarUnit )
fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit |
NSMinuteCalendarUnit | NSSecondCalendarUnit )
fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
// Notification will fire in one minute
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = [eventText text];
// Set the action button
localNotif.alertAction = #"View";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue"
forKey:#"someKey"];
localNotif.userInfo = infoDict;
// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[self.tableview reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
datePicker = nil;
tableview = nil;
eventText = nil;
}
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// We only have one section
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of notifications
return [[[UIApplication sharedApplication] scheduledLocalNotifications] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
// Get list of local notifications
NSArray *notificationArray = [[UIApplication sharedApplication]
scheduledLocalNotifications];
UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];
// Display notification info
[cell.textLabel setText:notif.alertBody];
[cell.detailTextLabel setText:[notif.fireDate description]];
return cell;
}
#end
You have to create an instance of the viewControllerfirst:
ViewController *viewController = [[ViewController alloc] init];
// set the frame, do other stuff..
[_window addSubview:viewController.view];
please check your AppDelegate code first
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
/******
YOUR CODE HERE
******/
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Ok so after doing some playing around. I was able to get the app to run without having to change the app delegate at all.
Not sure why in the tutorial he states to do so.
Thanks for you help.

Adding two values in the strings together in ios

I would like to add the values in the strings together which are in the format:"HH:mm:ss.SSS" and display it back again. In my case, it is adding timeString with difference to get currentString. I am not sure of the correct way of doing it. I am definitely doing it wrongly. The problem i face is that when i click the stop button and click start again, it starts off from 0 again.. I would like it to start off from the same spot where it left off..
The portion of the code is here:
-(void)updateTimer{
currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
timeString=[dateFormatter stringFromDate:timerDate];
currentString=[dateFormatter stringFromDate:timerDate];
//double doubleOfString = [timeString doubleValue] + [difference doubleValue];
//currentString = [NSString stringWithFormat:#"%f",doubleOfString];
lbl.text = currentString;
}
The entire code is here:
Viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
UILabel *lbl;
NSTimer *stopTimer;
NSDate *startDate,*currentDate;
BOOL running,lap;
UIButton *bttn;
NSMutableArray *tableItems;
NSString *timeString,*currentString,*difference;
UITableView *tableview;
}
#property (strong,nonatomic) IBOutlet UILabel *lbl;
#property (strong,nonatomic) IBOutlet UIButton *bttn;
#property (strong,nonatomic) NSMutableArray *tableItems;
#property (strong,nonatomic) NSString *timeString;
#property (strong,nonatomic) IBOutlet UITableView *tableview;
-(IBAction)startPressed:(id)sender;
-(IBAction)resetPressed:(id)sender;
-(void)updateTimer;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize lbl,bttn,tableItems,timeString,tableview;
- (void)viewDidLoad
{
[super viewDidLoad];
lbl.text = #"00.00.00.000";
running = FALSE;
lap = FALSE;
difference = #"0";
startDate = [NSDate date];
tableItems = [[NSMutableArray alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)startPressed:(id)sender{
if(!running){
running = TRUE;
lap = TRUE;
[sender setTitle:#"Stop" forState:UIControlStateNormal];
[bttn setTitle:#"Lap" forState:UIControlStateNormal];
if (stopTimer == nil) {
stopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
}else{
running = FALSE;
lap = FALSE;
startDate = currentDate;
difference = currentString;
[sender setTitle:#"Start" forState:UIControlStateNormal];
[bttn setTitle:#"Restart" forState:UIControlStateNormal];
[stopTimer invalidate];
stopTimer = nil;
}
}
-(void)updateTimer{
currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
timeString=[dateFormatter stringFromDate:timerDate];
currentString=[dateFormatter stringFromDate:timerDate];
double doubleOfString = [timeString doubleValue] + [difference doubleValue];
//currentString = [NSString stringWithFormat:#"%f",doubleOfString];
lbl.text = currentString;
}
-(IBAction)resetPressed:(id)sender{
if (!lap) {
[stopTimer invalidate];
stopTimer = nil;
tableItems = [[NSMutableArray alloc] init];
startDate = [NSDate date];
lbl.text = #"00.00.00.000";
running = FALSE;
}
else{
[tableItems insertObject:timeString atIndex:0];
[tableview reloadData];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return tableItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Step 1:Check whether if we can reuse a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
//Step2: If there are no new cells to reuse,create a new one
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"cell"];
//UIView *v = [[UIView alloc] init];
//v.backgroundColor = [UIColor redColor];
//cell.selectedBackgroundView = v;
//changing the radius of the corners
//cell.layer.cornerRadius = 10;
}
//Step 3: Set the cell text content
cell.textLabel.text = [tableItems objectAtIndex:indexPath.row];
//Step 4: Return the row
return cell;
}
#end
I welcome any other corrections that you can suggest...
I would kindly suggest not applying math to strings.
I mean:
What's the sum of the words “apple” and “Millenium Falcon”? Doesn’t make any sense, does it?
So why are you trying to form an addition of two strings, when you had a perfectly good number (timeInterval) — a type perfectly suitable to perform algebraic operations on?
PS:
NSDateFormatter instances want to be reused. Stash yours in an instance variable.
Your update timer function will be:Firstly add int counter in .h file . In viewDidLoad counter = 0;
-(void)updateTimer{
counter ++;
int hours = counter / 3600 ;
int minutes = (counter / 60) - (hours * 60);
int seconds = counter - (hours * 3600) - (minutes * 60);
lbl.text = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
}

how to call date on cell selected from datepickerview in iphone

hi friend i have to make date application
i have groped tableview.i have one section and two row
when my application start i am showing default date on both cell on first cell i was showing today day+1 and on nextcell i am showing today day+6 they i can see but
- (id)init
{
[super initWithStyle:UITableViewStyleGrouped];
NSDate *todaysDate = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:1];
app.selectionData.fromDateSelected = [gregorian dateByAddingComponents:dateComponents toDate:todaysDate options:0];
[dateComponents release];
[gregorian release];
//this is for 6day
NSDate *todaysDate1 = [NSDate date];
NSCalendar *gregorian1 = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents1 = [[NSDateComponents alloc] init];
[dateComponents1 setDay:6];
app.selectionData.toDateSelected = [gregorian1 dateByAddingComponents:dateComponents1 toDate:todaysDate1 options:0];
[dateComponents1 release];
[gregorian1 release];
return self;
}
but know i want if
the first cell selected date is changed from date pickerview and second cell date is less than the first cell selected date then change the second cell date automatically to first cell selected date+5 please help me how to solve it what the change i have to do in my code wher i am show by default this for once time on this this is my code on run time
this code i writemin my firstview controller class where i am show this date when my application start
in tableviewcellrowAtindexpath
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd/MM/yyyy"];
NSString*fromDate = [dateFormat stringFromDate:app.selectionData.fromDateSelected];
// NSString *toDate = [dateFormat stringFromDate:targetDate1];
NSString *toDate = [dateFormat stringFromDate:app.selectionData.toDateSelected];
if ([indexPath row] == 0 && [indexPath section] == 1)
{
cell.textLabel.text=#"From Date";
cell.detailTextLabel.text=fromDate;
NSLog(#"this is for fromDate:%#",fromDate);
}
if ([indexPath row] == 1 && [indexPath section] == 1)
{
cell.textLabel.text=#"To Date";
cell.detailTextLabel.text=toDate;
}
[dateFormat release];
dateFormat = nil;
this is code od dateview where i put my datepicker from here i selected date
- (void)viewDidLoad
{
// if(datePicker != nil && [datePicker retainCount] > 0)
// {
// [datePicker release];
//
// datePicker = nil;
//}
datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 40, 0, 0)];
[datePicker addTarget:self action:#selector(DateChangeForFinalPayMent) forControlEvents:UIControlEventValueChanged];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.date = [NSDate date];
datePicker.minimumDate = [NSDate date];
[self.view addSubview:datePicker];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(void)DateChangeForFinalPayMent{
if ([selectionData type] == 0)
[selectionData setFromDateSelected:[datePicker date]];
else
[selectionData setToDateSelected:[datePicker date]];
// [super viewWillDisappear:animated];
}
I wrote an example project for you that does this
Basically - look at the delegate method of the picker view controller.
It sends back a new date - and from that date you can calculate the second date and reload your table view.
This is the code to get date from datepicker. 1st select the date & then select the cell you need to update.
NSString *dateString = nil;
-(void)DateChangeForFinalPayMent:(id)sender {
NSLocale *usLocale = [[[NSLocale alloc]initWithLocaleIdentifier:#"en_US"] autorelease];
NSDate *pickerDate = [self.datePicker date];
NSString *selectionString = [[NSString alloc] initWithFormat:#"%#", [pickerDate descriptionWithLocale:usLocale]];
NSLog(#"string =%#",selectionString);
dateString = selectionString;
[selectionString release];
}
On selecting the cell Perform this operation
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath.row;
NSArray *array = [NSArray arrayWithObject:indexPath];
[tablview reloadRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationFade];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//some condition over here
if(selectedIndex == indexPath.row)
cell.textLabel = dateString;
//some condition over her
}
You use this code according to your implementation..

Retrieve EKEventStore

I have a table with all the users events in my app. When you click on one of the events I would like it to save the event name, location, start date, end date, notes in a UILabel. How can I do this my table code is bellow. I have tried searching the web for hours and nothing comes up.
Below is the code for the table
//eventsTable.h
#import <UIKit/UIKit.h>
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
#interface eventsTable : UIViewController <UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate,UIPopoverControllerDelegate,UINavigationControllerDelegate> {
IBOutlet UITableView *Table;
EKEventStore *eventStore;
EKEvent *event;
EKEventViewController *detailViewController;
EKCalendar *defaultCalendar;
NSMutableArray *eventsList;
}
-(IBAction) done;
- (NSArray *)fetchEventsForToday;
#property (nonatomic, retain)
IBOutlet UITableView *Table;
#property (nonatomic, retain) EKEventStore *eventStore;
#property (nonatomic, retain) EKCalendar *defaultCalendar;
#property (nonatomic, retain) NSMutableArray *eventsList;
#property (nonatomic, retain) EKEventViewController *detailViewController;
#end
//eventsTable.m
#import "eventsTable.h"
#implementation eventsTable
#synthesize eventsList, eventStore, defaultCalendar, detailViewController,Table;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Events List";
// Initialize an event store object with the init method. Initilize the array for events.
self.eventStore = [[EKEventStore alloc] init];
self.eventsList = [[NSMutableArray alloc] initWithArray:0];
// Get the default calendar from store.
self.defaultCalendar = [self.eventStore defaultCalendarForNewEvents];
// Create an Add button
// Fetch today's event on selected calendar and put them into the eventsList array
[self.eventsList addObjectsFromArray:[self fetchEventsForToday]];
[Table reloadData];
}
-(IBAction) done{
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark -
#pragma mark Table view data source
// Fetching events happening in the next 24 hours with a predicate, limiting to the default calendar
- (NSArray *)fetchEventsForToday {
NSDate *startDate1 = [NSDate date];
// endDate is 1 day = 60*60*24 seconds = 86400 seconds from startDate
NSDate *endDate1 = [NSDate distantFuture];
// Create the predicate. Pass it the default calendar.
NSArray *calendarArray = [NSArray arrayWithObject:defaultCalendar];
//NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate
// calendars:calendarArray];
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate1 endDate:endDate1 calendars:calendarArray];
// Fetch all events that match the predicate.
NSArray *events = [self.eventStore eventsMatchingPredicate:predicate];
events =
[events sortedArrayUsingSelector:
#selector(compareStartDateWithEvent:)];
self.eventsList = [NSMutableArray arrayWithArray:events];
[Table reloadData];
return events;
}
#pragma mark -
#pragma mark Table View
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return eventsList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *result = nil;
if ([tableView isEqual:self.Table] == YES){
static NSString *EventsCellIdentifier = #"Events";
/* We have the index path so let's get the corresponding
event from the array of events */
EKEvent *event1 = [self.eventsList
objectAtIndex:indexPath.row];
/* Try to get a reusable table cell */
result =
[tableView dequeueReusableCellWithIdentifier:EventsCellIdentifier];
if (result == nil){
result = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:EventsCellIdentifier] autorelease];
}
/* The title text of the cell will be the title of the event */
result.textLabel.text = event1.title;
result.textLabel.font = [UIFont boldSystemFontOfSize:16.0f];
result.detailTextLabel.font = [UIFont systemFontOfSize:12.0f];
/* Now let's format the date and the time of the event
and display it as the subtitle of the cell */
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components =
[calendar components:
NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit |
NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSSecondCalendarUnit
fromDate:event1.startDate];
NSDateComponents *components1 =
[calendar components:
NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit |
NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSSecondCalendarUnit
fromDate:event1.endDate];
if ([components hour] == 0 &&
[components minute] == 0 &&
[components second] == 0){
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];
NSDate *date = [calendar dateFromComponents: components1];
NSString *string = [NSDateFormatter localizedStringFromDate: date dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterNoStyle];
NSDate *date1 = [calendar dateFromComponents: components];
NSString *string1 = [NSDateFormatter localizedStringFromDate: date1 dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterNoStyle];
result.detailTextLabel.text =
[NSString stringWithFormat:#"All Day from %# - %#",string1,string,
(long)[components month],
(long)[components day],
(long)[components year],
(long)[components1 month],
(long)[components1 day],
(long)[components1 year]];
} else {
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];
NSDate *date = [calendar dateFromComponents: components1];
NSString *string = [NSDateFormatter localizedStringFromDate: date dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterShortStyle];
NSDate *date1 = [calendar dateFromComponents: components];
NSString *string1 = [NSDateFormatter localizedStringFromDate: date1 dateStyle: NSDateFormatterShortStyle timeStyle: NSDateFormatterShortStyle];
result.detailTextLabel.text =
[NSString stringWithFormat:#"%# - %#",string1,string,
(long)[components month],
(long)[components day],
(long)[components year],
(long)[components hour],
(long)[components minute],
(long)[components1 hour],
(long)[components1 minute]];
}
}
return(result);
[event release];
[eventsList release];
[eventStore release];
[result release];
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (void)viewDidUnload {
self.eventsList = nil;
self.view = nil;
self.Table = nil;
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
[Table release];
[eventStore release];
[eventsList release];
[defaultCalendar release];
[detailViewController release];
}
#end
Remove the [Table reloadData] and [self.eventsList addObjectsFromArray:[self fetchEventsForToday]]; from viewDidload and place it in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
[self.eventsList addObjectsFromArray:[self fetchEventsForToday]];
return [self.eventsList count];
}
Hope this will help you. but it will be better to debug the method [self fetchEventsForToday].

NSDate basic usage error

Next to a label showing the value of a slider i want to show the date that corresponds to a start date + the number of days in slider value units.
When i move the slider the app crashes in the Simulator. As far as i could find out that happens when i try to create a new NSDate field and my startDate object being "out of scope".
Reading a lot regarding retaining and releasing NSDate documentation had not helped me until now, because the documentation is so abstract that it seems to me that I'm not able to find the relevant part(s) in the documentation. I hope to understand more by example.
So what's wrong with the following code (and from where in the documentation should a beginner have learned that) ?
#import <UIKit/UIKit.h>
#interface SliderDateViewController : UIViewController {
UILabel *dateLabel;
UILabel *sliderValueLabel;
UISlider *slider;
NSDate *startDate;
}
#property (nonatomic, retain) IBOutlet UILabel *dateLabel;
#property (nonatomic, retain) IBOutlet UILabel *sliderValueLabel;
#property (nonatomic, retain) IBOutlet UISlider *slider;
#property (nonatomic, retain) NSDate *startDate;
-(IBAction)sliderValueChanged:(UISlider *)theSlider;
#end
#import "SliderDateViewController.h"
#implementation SliderDateViewController
#synthesize dateLabel;
#synthesize sliderValueLabel;
#synthesize slider;
#synthesize startDate;
- (void)viewDidLoad {
[super viewDidLoad];
dateLabel.text = #"01.01.2010";
sliderValueLabel.text = #"0";
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:#"dd.MM.yyyy"];
self.startDate = [inputFormatter dateFromString:dateLabel.text];
NSLog(#"startDate: ", self.startDate.description);
[inputFormatter release];
}
-(IBAction)sliderValueChanged:(UISlider *)theSlider {
int sliderValueAsInt = (int)(theSlider.value + 0.5f);
NSString *newText = [[NSString alloc] initWithFormat:#"%d", sliderValueAsInt];
sliderValueLabel.text = newText;
[newText release];
// Next line following the comment crashed with
// *** -[CFDate release]: message sent to deallocated instance 0x3b07d10
NSDate *newDate = [startDate addTimeInterval:86400 * sliderValueAsInt];
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:#"dd.MM.yyyy"];
dateLabel.text = [outputFormatter stringFromDate:newDate];
[outputFormatter release];
// [newDate release] // <- this was the error
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[dateLabel release];
[sliderValueLabel release];
[slider release];
[startDate release];
[super dealloc];
}
#end
Firstly, -addTimeInterval: is deprecated. Use -dateByAddingTimeInterval: instead.
NSDate *newDate = [startDate addTimeInterval:86400 * sliderValueAsInt];
[startDate release];
startDate = newDate;
[newDate release];
Since -addTimeInterval: is not an +alloc/-copy/-create method, the newDate is owned by no one and you should not -release it. To obtain the ownership you need to
NSDate *newDate = [startDate addTimeInterval:86400 * sliderValueAsInt];
if (newDate != startDate) {
[startDate release];
startDate = [newDate retain];
}
which can be conveniently rewritten as
self.startDate = [startDate addTimeInterval:86400 * sliderValueAsInt];
Judging from the code logic, the startDate should be kept immutable. That means the startDate = newDate; stuff shouldn't appear at all. Delete the 3 lines below NSDate *newDate = [startDate ...]; and the code shall work fine.