I'm trying to make an app with a calendar being displayed and as soon as a day on the calendar (each day is a UIView with a tap gesture) is tapped, all calendar appointments for that day should be displayed in a UITableView. I've got this working, but there's a big lag between when the tap occurs and when the data is actually populated into the UITableView. Here's my code:
EKEventStore *store = [[EKEventStore alloc] init];
//Access Granted to Calendar by user
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
// Create the start date components
NSDateFormatter *startFormatter = [[NSDateFormatter alloc]init];
[startFormatter setDateFormat:#"MM/dd/yyyy hh:mm a"];
NSString *monthNumberString = [NSString stringWithFormat:#"%i", month];
NSString *startDateString = [[[[[monthNumberString stringByAppendingString:#"/"] stringByAppendingString:dLabel.text] stringByAppendingString:#"/"] stringByAppendingString:yearString] stringByAppendingString:#" 12:01 am"];
NSDate *start = [startFormatter dateFromString:startDateString];
NSLog(#"Start Date: %#", startDateString);
// Create the end date components
NSDateFormatter *endFormatter = [[NSDateFormatter alloc]init];
[endFormatter setDateFormat:#"MM/dd/yyyy hh:mm a"];
NSString *endDateString = [[[[[monthNumberString stringByAppendingString:#"/"] stringByAppendingString:dLabel.text] stringByAppendingString:#"/"] stringByAppendingString:yearString] stringByAppendingString:#" 11:59 pm"];
NSDate *end = [endFormatter dateFromString:endDateString];
NSLog(#"End Date: %#", endDateString);
// Create the predicate from the event store's instance method
NSPredicate *predicate = [store predicateForEventsWithStartDate:start
endDate:end
calendars:nil];
// Fetch all events that match the predicate
events = [store eventsMatchingPredicate:predicate];
//Sort the array
events = [events sortedArrayUsingSelector:#selector(compareStartDateWithEvent:)];
int eventCount = [events count];
NSLog(#"%i", eventCount);
for (int i=0; i<eventCount; i++) {
EKEvent *theEvent = [events objectAtIndex:i];
NSLog (#"Element %i = %#", i, theEvent.title);
}
UITableView *dayTableView = [[UITableView alloc] initWithFrame:CGRectMake(360, 0, 300, 550)
style:UITableViewStylePlain];
dayTableView.backgroundColor = lightBlueColor;
dayTableView.separatorColor = [UIColor clearColor];
dayTableView.delegate = self;
dayTableView.dataSource = self;
[super addSubview:dayTableView];
}];
UITableview Delegate Functions:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog (#"I made a section!");
return 1; //count of section
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog (#"I made %i rows!", [events count]);
return [events count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *c = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"mycell"];
EKEvent *theEvent = [events objectAtIndex:indexPath.row];
c.textLabel.text = theEvent.title;
NSLog (#"Cell %i = %#", indexPath.row, theEvent.title);
//c.textLabel.text = #"Calendar Event Goes Here";
c.textLabel.textColor = [UIColor whiteColor];
//NSLog (#"I made a cell!");
return c;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 35;
}
Any help would be greatly appreciated.
Without profiling it is difficult to say what the bottleneck of your code is. However, based on previous experience I would say that it is the lines that looks like
NSString *startDateString = [[[[[monthNumberString stringByAppendingString:#"/"] stringByAppendingString:dLabel.text] stringByAppendingString:#"/"] stringByAppendingString:yearString] stringByAppendingString:#" 12:01 am"];
At least if it is called +20000x (or something) a second. First of all it would be more convienient to write this as
NSString *startDateString = [NSString stringWithFormat:#"%#/%#/%# 12:01 am", monthNumberString, dLabel.text, yearString];
But I fear this would not speed up your program much. I would recommend going back to plain C code and use e.g. sprintf instead. You can look up the syntax of it here as well as some examples of use.
I found the answer. The problem is here:
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
the way that the event store is accessed is different on iOS6 and iOS5. Here's a link that shows the correct way of doing it:
http://fostah.com/ios/2012/09/28/ios6-event-edit.html
Related
I have an array of objects that contain NSDate property in them. And I'm populating them successfully in a UITableView.
I want to distribute them (the objects) in UITableView sections according to their month.
How can I do that?
Please review this code once.It may help you.
NSMutableDictionary * dictArrData; //declare dictionary global
-(void)createHederAndCellArray
{
dictArrData=[[NSMutableDictionary alloc]init];
for(int i=0;i<arrHistory.count;i++)
{
yourObject *pastorders=[arrHistory objectAtIndex:i];
if([dictArrData objectForKey:pastorders.paymentDate])
{
NSMutableArray *arrTemp=[dictArrData objectForKey:pastorders.paymentDate];
[arrTemp addObject:pastorders];
[dictArrData setObject: arrTemp forKey:pastorders.paymentDate];
}
else
{
NSMutableArray * arrTemp = [[NSMutableArray alloc]init];
[arrTemp addObject:pastorders];
[dictArrData setObject: arrTemp forKey:pastorders.paymentDate];
}
}
NSLog(#“check dictionary %#",[dictArrData description]);
}
[self createHederAndCellArray]; ----> this method you need to call after adding data in your array and than set code in tableview as below.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [dictArrData allKeys].count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *allValues=(NSArray*)[dictArrData objectForKey:[[dictArrData allKeys] objectAtIndex:section]];
return [allValues count];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 22, tableView.frame.size.width,15)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width,25)];
[label setFont:[UIFont systemFontOfSize:14]];
label.textAlignment=NSTextAlignmentLeft;
label.textColor=[UIColor whiteColor];
NSString *sectionTitle=[NSString stringWithFormat:#"%#" ,[[dictArrData allKeys] objectAtIndex:section]];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSDate *date = [dateFormatter dateFromString:sectionTitle];
dateFormatter.dateFormat = #“MMM";
NSString *sectionTitle =[NSString stringWithFormat:#" %#", [dateFormatter stringFromDate:date]];
[view addSubview:imgvw];
[view addSubview:label];
[label setText:sectionTitle];
return view;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
yourcell *cell = [tableView dequeueReusableCellWithIdentifier:#“yourcellidentifier” forIndexPath:indexPath];
if (cell == nil)
{
cell = [[yourcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"yourcellidentifier"];
}
#try
{
//keyArr=[self sortKeyAccordingTodate];
NSArray *allValues=[dictArrData objectForKey:[[dictArrData allKeys] objectAtIndex:indexPath.section]];
if(allValues.count >0 )
{
yourObject *pastorder=[allValues objectAtIndex:indexPath.row];
cell.lblProductname.text=pastorder.itemName;
}
}
#catch (NSException *exception) {
NSLog(#"Exception :%#",exception.description);
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 25;
}
To sort according to date than you need to sort dictionary keys.
-(NSArray *)sortKeyAccordingTodate
{
NSArray* sorted = [[dictArrData allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSDate *date = [dateFormatter dateFromString:obj1];
NSDate *date1 = [dateFormatter dateFromString:obj2];
if (date > date1) {
return (NSComparisonResult)NSOrderedAscending;
}
if (date < date1) {
return (NSComparisonResult)NSOrderedDescending;
}
return (NSComparisonResult)NSOrderedSame;
}];
return sorted;
}
if you use sort method than you need to use [self sortKeyAccordingTodate] instead [dictArrData allKeys]
Hope this will help you :)
You can group the objects (e.g. Person) by using below code:
NSMutableArray* arrObjects = [NSMutableArray new];
for (int i=0;i<12;i++) {
Person* p1 = [Person new];
p1.name = [NSString stringWithFormat:#"ABC %d", i+1];
p1.date = [[NSDate date] dateByAddingTimeInterval:60*60*24*30*i];
[arrObjects addObject:p1];
}
// add blank arrays for 12 months
NSMutableArray* matrixObjects = [NSMutableArray new];
for (int i=0; i<12; i++) {
[matrixObjects addObject:[NSMutableArray new]];
}
NSCalendar* calendar = [NSCalendar currentCalendar];
for (Person* p in arrObjects) {
int month = (int) [[calendar components:NSCalendarUnitMonth fromDate:p.date] month];
[matrixObjects[month-1] addObject:p];
}
// print resutls
for (int i=0; i<matrixObjects.count; i++) {
NSLog(#"Objects in Section %d", i);
for (Person* p in matrixObjects[i]) {
NSLog(#" ROW: %# %#", p.name, p.date.description);
}
}
Which gives output as below:
Objects in Section 0
ROW: ABC 11 2017-01-29 11:55:49 +0000
Objects in Section 1
ROW: ABC 12 2017-02-28 11:55:49 +0000
Objects in Section 2
Objects in Section 3
ROW: ABC 1 2016-04-04 11:55:49 +0000
Objects in Section 4
ROW: ABC 2 2016-05-04 11:55:49 +0000
Objects in Section 5
ROW: ABC 3 2016-06-03 11:55:49 +0000
Objects in Section 6
ROW: ABC 4 2016-07-03 11:55:49 +0000
Objects in Section 7
ROW: ABC 5 2016-08-02 11:55:49 +0000
Objects in Section 8
ROW: ABC 6 2016-09-01 11:55:49 +0000
Objects in Section 9
ROW: ABC 7 2016-10-01 11:55:49 +0000
ROW: ABC 8 2016-10-31 11:55:49 +0000
Objects in Section 10
ROW: ABC 9 2016-11-30 11:55:49 +0000
Objects in Section 11
ROW: ABC 10 2016-12-30 11:55:49 +0000
matrixObjects is the array of 12 month wise array of you objects, which you can use in numberOfSections and numberOfRows delegate methods
I want to get an EKEvent from an array iOS. But I have one problem. If I put my code lines in the viewDidLoad method, it works.
But if I make it in a button from a table view: (-(IBAction)button:(UiButton *)sender) it gets an EKEvent, but doesn't note the event.
Thats my code:
EKEvent *event =[eventArray objectAtIndex:0]
NSString *string = event.notes
Thats the complete code:
- (void)viewDidLoad {
selectedDate = [NSDate date];
[super viewDidLoad];
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted == NO) {
UIViewController *controller = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"needAccess"];
[self.view addSubview:controller.view];
[self addChildViewController:controller];
}
}];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *start = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:selectedDate options:0];
NSDate *end = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[selectedDate dateByAddingTimeInterval:60*60*24] options:0];
NSPredicate *predicate = [store predicateForEventsWithStartDate:start endDate:end calendars:nil];
eventArray = [store eventsMatchingPredicate:predicate];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [eventArray count];
}
- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [table dequeueReusableCellWithIdentifier: #"EventCell"];
EKEvent *event = [eventArray objectAtIndex:indexPath.row];
UIButton *headline = (UIButton *)[cell viewWithTag:1];
headline.layer.cornerRadius = headline.frame.size.width / 2;
headline.clipsToBounds = YES;
headline.tag = indexPath.row;
[headline addTarget:self action:#selector(headlineButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
-(void)headlineButton:(UIButton*)sender {
EKEvent *event = [eventArray objectAtIndex:0];
NSArray *notes = [event.notes componentsSeparatedByString:#"//"];
NSString *latitude = [notes objectAtIndex:1];
NSString *longitude = [notes objectAtIndex:2];
}
That's probably because neither the cell or the button on the cell have an EKEvent property.
Your cell is loaded from a model. The event data is likely in the model
If your button or cell needs to access event data, you have to decide how the data flows through your app. You also want to have a single source of truth for the event, so no matter what your app's state, you always are certain about details for an event, whether editing or updating or persisting or deleting or inserting an event.
These are questions you may want to tackle, so you have a really good understanding where and how you store these details, and how your cell button should access an event's note.
I want self.agendaTable to run reloadData when the calendarDidDateSelected runs, but that doesn't seem to happen. As far as I can tell, the table is setup properly, and I have it set to update the contents of self.agendaTableArray in cellForRowAtIndexPath when it reloads. What am I doing wrong?
I'm setting up the table like so:
- (void)viewDidLoad
{
[super viewDidLoad];
// Set up Day Agenda table
CGRect frame = CGRectMake(0,380,self.view.frame.size.width,self.view.frame.size.height);
UITableView *agendaTable = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
agendaTable.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
agendaTable.delegate = self;
agendaTable.dataSource = self;
[agendaTable reloadData];
[self.view addSubview:agendaTable];
/////
self.agendaTableArray = [[NSArray alloc] init];
self.agendaTableArray = #[#"No events today!"];
[self.calendar setMenuMonthsView:self.calendarMenuView];
[self.calendar setContentView:self.calendarContentView];
[self.calendar setDataSource:self];
}
Relevant cellForRowAtIndexPath code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
///...earlier code snipped for brevity
// title of the item
if (self.datePicked == [NSNumber numberWithInt:16]) {
NSLog(#"cellForRowAtIndexPath says self.datePicked is 16");
self.agendaTableArray = #[#"Dinner with Rebekah", #"Meeting with John"];
}
else {
self.agendaTableArray = #[#"No events today!"];
}
cell.textLabel.text = self.agendaTableArray[indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:14];
return cell;
}
calling calendarDidDateSelected like so:
- (void)calendarDidDateSelected:(JTCalendar *)calendar date:(NSDate *)date
{
NSLog(#"Date: %#", date);
// NSDateFormatter is used to create a date from a string
// static keyword is used to avoid create a new instance each time calendarDidDateSelected is called
static NSDateFormatter *dateFormatter = nil;
if(!dateFormatter){
dateFormatter = [NSDateFormatter new];
dateFormatter.dateFormat = #"yyyy-MM-dd"; // Read the documentation for dateFormat
}
// If date picked is June 16th
NSDate *juneSixteenth = [dateFormatter dateFromString:#"2015-06-16"];
if([juneSixteenth compare:date] == NSOrderedSame){
self.datePicked = [NSNumber numberWithInt:16];
NSLog(#"self.datePicked: %#", self.datePicked);
}
[self.agendaTable reloadData];
}
Are you properly assigning your agendaTable you created to your 'agendaTable' property in your viewDidLoad?
self.agendaTable = agendaTable;
I have retrieved my events from a shared google calendar i IOS, and are displaying them in a tableview. As for right now, they're simplty shown with the event title as the title, and the eventtime as the subtitle. I'd like to use the date (eventtime) as a section header in stead, so that all events on for instance march 31st where shown in a group, with the time as a "right detail"
My code looks like this:
#interface MasterViewController () {
NSArray *events;
}
#end
#implementation MasterViewController
-(void)viewDidAppear:(BOOL)animated
{
//show loader view
//[HUD showUIBlockingIndicatorWithText:#"Fetching JSON"];
//make HTTP call
NSString* searchCall = [NSString stringWithFormat:#"http://www.google.com/calendar/feeds/kao1d80fd2u5kh7268caop11o4%%40group.calendar.google.com/public/full?alt=json"];
[JSONHTTPClient getJSONFromURLWithString: searchCall
completion:^(NSDictionary *json, JSONModelError *err) {
//got JSON back
NSLog(#"Got JSON from web: %#", json);
if (err) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:[err localizedDescription]
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles: nil] show];
return;
}
//initialize the models
events = [CalendarModel arrayOfModelsFromDictionaries:
json[#"feed"][#"entry"]
];
if (events) NSLog(#"Loaded successfully models");
//show the videos
[self.tableView reloadData];
}];
}
;
#pragma mark - table methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return events.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CalendarModel* event = events[indexPath.row];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
NSDate *gmtDate = [formatter dateFromString: [[event.time objectAtIndex:0] startTime]];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%#",
event.title
];
cell.detailTextLabel.text = [formatter stringFromDate: gmtDate];
return cell;
}
#end
I have found this code online, but he doesn't get data as JSON, but from an iPhone calendar, i believe.
#interface MasterViewController ()
#property (strong, nonatomic) NSMutableDictionary *sections;
#property (strong, nonatomic) NSArray *sortedDays;
#property (strong, nonatomic) NSDateFormatter *sectionDateFormatter;
#property (strong, nonatomic) NSDateFormatter *cellDateFormatter;
- (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate;
- (NSDate *)dateByAddingYears:(NSInteger)numberOfYears toDate:(NSDate *)inputDate;
#end
#implementation MasterViewController
#synthesize sections;
#synthesize sortedDays;
#synthesize sectionDateFormatter;
#synthesize cellDateFormatter;
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSDate *now = [NSDate date];
NSDate *startDate = [self dateAtBeginningOfDayForDate:now];
NSDate *endDate = [self dateByAddingYears:1 toDate:startDate];
EKEventStore *eventStore = [[EKEventStore alloc] init];
NSPredicate *searchPredicate = [eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil];
NSArray *events = [eventStore eventsMatchingPredicate:searchPredicate];
self.sections = [NSMutableDictionary dictionary];
for (EKEvent *event in events)
{
// Reduce event start date to date components (year, month, day)
NSDate *dateRepresentingThisDay = [self dateAtBeginningOfDayForDate:event.startDate];
// If we don't yet have an array to hold the events for this day, create one
NSMutableArray *eventsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
if (eventsOnThisDay == nil) {
eventsOnThisDay = [NSMutableArray array];
// Use the reduced date as dictionary key to later retrieve the event list this day
[self.sections setObject:eventsOnThisDay forKey:dateRepresentingThisDay];
}
// Add the event to the list for this day
[eventsOnThisDay addObject:event];
}
// Create a sorted list of days
NSArray *unsortedDays = [self.sections allKeys];
self.sortedDays = [unsortedDays sortedArrayUsingSelector:#selector(compare:)];
self.sectionDateFormatter = [[NSDateFormatter alloc] init];
[self.sectionDateFormatter setDateStyle:NSDateFormatterLongStyle];
[self.sectionDateFormatter setTimeStyle:NSDateFormatterNoStyle];
self.cellDateFormatter = [[NSDateFormatter alloc] init];
[self.cellDateFormatter setDateStyle:NSDateFormatterNoStyle];
[self.cellDateFormatter setTimeStyle:NSDateFormatterShortStyle];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - Date Calculations
- (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate
{
// Use the user's current calendar and time zone
NSCalendar *calendar = [NSCalendar currentCalendar];
NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
[calendar setTimeZone:timeZone];
// Selectively convert the date components (year, month, day) of the input date
NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:inputDate];
// Set the time components manually
[dateComps setHour:0];
[dateComps setMinute:0];
[dateComps setSecond:0];
// Convert back
NSDate *beginningOfDay = [calendar dateFromComponents:dateComps];
return beginningOfDay;
}
- (NSDate *)dateByAddingYears:(NSInteger)numberOfYears toDate:(NSDate *)inputDate
{
// Use the user's current calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setYear:numberOfYears];
NSDate *newDate = [calendar dateByAddingComponents:dateComps toDate:inputDate options:0];
return newDate;
}
#pragma mark - UITableViewDataSource methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.sections count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDate *dateRepresentingThisDay = [self.sortedDays objectAtIndex:section];
NSArray *eventsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
return [eventsOnThisDay count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDate *dateRepresentingThisDay = [self.sortedDays objectAtIndex:section];
return [self.sectionDateFormatter stringFromDate:dateRepresentingThisDay];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *reuseIdentifier = #"EventTitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
NSDate *dateRepresentingThisDay = [self.sortedDays objectAtIndex:indexPath.section];
NSArray *eventsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
EKEvent *event = [eventsOnThisDay objectAtIndex:indexPath.row];
cell.textLabel.text = event.title;
if (event.allDay) {
cell.detailTextLabel.text = #"all day";
} else {
cell.detailTextLabel.text = [self.cellDateFormatter stringFromDate:event.startDate];
}
return cell;
}
#end
Is there a way for me to use my json event.startdate as a section header?
Personally, I would ignore the code you posted second there because its not what you are trying to do.
The part of the code where you set you header and subtitle are these two lines:
cell.textLabel.text = [NSString stringWithFormat:#"%#",event.title];
cell.detailTextLabel.text = [formatter stringFromDate: gmtDate];
So if you want the heading to be the date, just place it as the cell.textLabel.text value.
So if you are wanting to do sections.
Make sure the number of sections is greater then 1.
Then you might want to take a look at these table methods. Just depending on what your exact case and customization needs are you can change it accordingly.
(NSString*) tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section{
}
(CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section{
}
(UIView*)tableView:(UITableView*)table viewForHeaderInSection:(NsInteger)section{
}
I hope this helps. I normally would have an example I just didn't have the most available time currently, but if need be I can provide one.
Take Care :)
Now I meet a strange situation, I need your help, and forgive my poor English.
When a UITableView, filled with NSArray, on the top, really reload data when I use [UITableView reloadData]. But, the table doesn't reload data if it's not on the top side. In fact, the app crashed. The strange thing is that the indexPath.section isn't the right value, bigger than real value. So the console said: index 2 beyond bounds [0..1].
Does anybody know why? Please give me a hand or a tips.
Below are some codes:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (pageCount == 0) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"IPOCalendarTableTitle" object:nil];
return 0;
} else {
NSMutableArray *arrayMonths = [stockArray objectAtIndex:pageIndex];
NSMutableArray *arrayDays = [arrayMonths objectAtIndex:0];
IPOListing *listing = [arrayDays objectAtIndex:0];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy/MM/dd";
NSDate *date = [formatter dateFromString:listing.date];
NSString *s = nil;
NSArray *arrayMonthEN = [NSArray arrayWithObjects:#"Jan", #"Feb", #"Mar", #"Apr", #"May", #"Jun", #"Jul", #"Aug", #"Sep", #"Oct", #"Nov", #"Dec", nil];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if ([delegate.currentLanguage isEqualToString:#"SC"]) {
formatter.dateFormat = #"yyyy年M月";
s = [formatter stringFromDate:date];
} else if ([delegate.currentLanguage isEqualToString:#"TC"]) {
formatter.dateFormat = #"yyyy年M月";
s = [formatter stringFromDate:date];
} else if ([delegate.currentLanguage isEqualToString:#"EN"]) {
int year = [[listing.date substringWithRange:NSMakeRange(0, 4)] intValue];
int month = [[listing.date substringWithRange:NSMakeRange(5, 2)] intValue];
s = [NSString stringWithFormat:#"%#, %d", [arrayMonthEN objectAtIndex:month - 1], year];
}
[formatter release];
NSArray *array = [NSArray arrayWithObjects:s, [NSNumber numberWithInt:pageCount], [NSNumber numberWithInt:pageIndex], nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"IPOCalendarTableTitle" object:array];
NSLog(#"%d", [arrayMonths count]);
return [arrayMonths count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSMutableArray *arrayMonths = [stockArray objectAtIndex:pageIndex];
NSMutableArray *arrayDays = [arrayMonths objectAtIndex:section];
return [arrayDays count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 36.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"IPOCalendarCellIdentifier";
IPOCalendarCell *cell = (IPOCalendarCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"IPOCalendarCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.lineLabel.backgroundColor = [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSLog(#"%d, %d", indexPath.section, indexPath.row);
NSMutableArray *arrayMonths = [self.stockArray objectAtIndex:pageIndex];
NSMutableArray *arrayDays = [arrayMonths objectAtIndex:indexPath.section];
IPOListing *listing = [arrayDays objectAtIndex:indexPath.row];
// configuration the cell...
return cell;
}
If indexPath.section isn't the right value, I'm pretty sure it has something to do with the value you return in - (NSInteger) numberOfRowsInSection:(UITableView *)tableView
Check this first, because If the size of your array is two, so as the value return by numberOfRowsInSection:, indexPath.section can't be equal or greater than this value.
Fixed. The problem is not here, it is about that two gang tables. When I use [UITableView setContentOffset] to table A, B will refresh too. In this case table A will reloadData twice, and when contentOffset of table is zero, it will reloadData only once. When table reloadData twice in quick time, it crashes. Thank all of you and I feel so sorry for my mistake.