We review both these scenarios in this example where we create and display a Date Picker when the user selects a cell in the Table View and then selects a date or time or both date and time depending date picker mode. We log the changes to the picker values with the help of the action method associated with the UIControlEventValueChanged event. In addition to that when we display the date picker we also add a button to the Navigation which the user can tap to close the date picker and set the value of the selected cell based on the picker value.
Interface file for the application delegate - DatePickerAppDelegate.h
#import <UIKit/UIKit.h> #import "MyViewController.h" @interface DatePickerAppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) UINavigationController *navigationController; @property (strong, nonatomic) MyViewController *myViewController; @end
Implementation file for the application delegate - DatePickerAppDelegate.h
#import "DatePickerAppDelegate.h" @implementation DatePickerAppDelegate @synthesize navigationController, myViewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. //create the navigation controller and add to the view navigationController = [[UINavigationController alloc] init]; [self.window addSubview:[self.navigationController view]]; //check if the my viewcontroller eixsts, otherwise create it if(self.myViewController == nil) { MyViewController *myTableView = [[MyViewController alloc] init]; self.myViewController = myTableView; } //push the viewcontroller into the navigation viewcontroller stack [self.navigationController pushViewController:self.myViewController animated:YES]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application{ //do nothing } - (void)applicationDidEnterBackground:(UIApplication *)application{ //do nothing } - (void)applicationWillEnterForeground:(UIApplication *)application{ //do nothing } - (void)applicationDidBecomeActive:(UIApplication *)application{ //do nothing } - (void)applicationWillTerminate:(UIApplication *)application{ //do nothing } @end
Interface file for view controller - MyViewController.h
#import <UIKit/UIKit.h> @interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) NSArray *dataArray; @property (nonatomic, strong) NSDateFormatter *dateFormatter1; @property (nonatomic, strong) NSDateFormatter *dateFormatter2; @property (nonatomic, strong) NSDateFormatter *dateFormatter3; @property (nonatomic, strong) UIDatePicker *myDatePicker; @property (nonatomic, strong) UIBarButtonItem *doneButton; @end
Implementation file for view controller - MyViewController.m
#import "MyViewController.h" @interface MyViewController () @end @implementation MyViewController @synthesize myTableView; @synthesize dataArray, dateFormatter1, dateFormatter2, dateFormatter3; @synthesize myDatePicker, doneButton; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; //create an array to help load Table View cells self.dataArray = [NSArray arrayWithObjects: @"Selected Date", @"Selected Time", @"Selected Date and Time", nil]; //date formatter with just date and no time self.dateFormatter1 = [[NSDateFormatter alloc] init]; [self.dateFormatter1 setDateStyle:NSDateFormatterFullStyle]; [self.dateFormatter1 setTimeStyle:NSDateFormatterNoStyle]; //date formatter with no date and just time self.dateFormatter2 = [[NSDateFormatter alloc] init]; [self.dateFormatter2 setDateStyle:NSDateFormatterNoStyle]; [self.dateFormatter2 setTimeStyle:NSDateFormatterLongStyle]; //date formatter with both date and time self.dateFormatter3 = [[NSDateFormatter alloc] init]; [self.dateFormatter3 setDateStyle:NSDateFormatterFullStyle]; [self.dateFormatter3 setTimeStyle:NSDateFormatterLongStyle]; //find the available space on the screen CGRect tableViewFrame = self.view.bounds; //set the background color and create the table view self.view.backgroundColor = [UIColor whiteColor]; self.myTableView = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStyleGrouped]; //set the delegate for the table view to self self.myTableView.delegate = self; //set the data source for the table view to self self.myTableView.dataSource = self; self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; //add the table view to the current view [self.view addSubview:self.myTableView]; } //set the number of rows to the number of entries in the array - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSInteger result = 0; result = [self.dataArray count]; return result; } //this to initialize the table view cell with data from the array - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = nil; //check if this our table view if ([tableView isEqual:self.myTableView]){ static NSString *TableViewCellIdentifier = @"MyCells"; cell = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier]; if (cell == nil){ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:TableViewCellIdentifier]; } //set the text for the cell with the data from the array cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row]; //depending on the row set the date to current date with the proper format switch (indexPath.row) { case 0: cell.detailTextLabel.text = [self.dateFormatter1 stringFromDate:[NSDate date]]; break; case 1: cell.detailTextLabel.text = [self.dateFormatter2 stringFromDate:[NSDate date]]; break; case 2: cell.detailTextLabel.text = [self.dateFormatter3 stringFromDate:[NSDate date]]; break; default: break; } } return cell; } //listen to changes in the date picker and just log them - (void) datePickerDateChanged:(UIDatePicker *)paramDatePicker{ if ([paramDatePicker isEqual:self.myDatePicker]){ NSLog(@"Selected date = %@", paramDatePicker.date); } } //when the cell is selected in the table view we need to display the picker - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ //which section and row was clicked on NSLog(@"Clicked on Section %d and Row %d", indexPath.section, indexPath.row); //get reference to the cell based on the index UITableViewCell *targetCell = [tableView cellForRowAtIndexPath:indexPath]; //if date picker doesn't exists then create it if(self.myDatePicker == nil){ self.myDatePicker = [[UIDatePicker alloc] init]; //set the action method that will listen for changes to picker value [self.myDatePicker addTarget:self action:@selector(datePickerDateChanged:) forControlEvents:UIControlEventValueChanged]; } //set the value of the picker based on the cell value and also set the proper picker mode switch (indexPath.row) { case 0: self.myDatePicker.date = [self.dateFormatter1 dateFromString:targetCell.detailTextLabel.text]; self.myDatePicker.datePickerMode = UIDatePickerModeDate; break; case 1: self.myDatePicker.date = [self.dateFormatter2 dateFromString:targetCell.detailTextLabel.text]; self.myDatePicker.datePickerMode = UIDatePickerModeTime; break; case 2: self.myDatePicker.date = [self.dateFormatter3 dateFromString:targetCell.detailTextLabel.text]; self.myDatePicker.datePickerMode = UIDatePickerModeDateAndTime; break; default: break; } //find the current table view size CGRect screenRect = [self.view frame]; NSLog(@"Screen frame %f %f", screenRect.origin.y, screenRect.size.height); //find the date picker size CGSize pickerSize = [self.myDatePicker sizeThatFits:CGSizeZero]; //set the picker frame CGRect pickerRect = CGRectMake(0.0, screenRect.origin.y + screenRect.size.height - pickerSize.height, pickerSize.width, pickerSize.height); self.myDatePicker.frame = pickerRect; //add the picker to the view [self.view addSubview:self.myDatePicker]; //create the navigation button if it doesn't exists if(self.doneButton == nil){ self.doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(dateSelected:)]; } //add the "Done" button to the right side of the navigation bar self.navigationItem.rightBarButtonItem = self.doneButton; } //method to call when the "Done" button is clicked - (void) dateSelected:(id)sender { //remove the "Done" button in the navigation bar self.navigationItem.rightBarButtonItem = nil; //find the current selected cell row in the table view NSIndexPath *indexPath = [self.myTableView indexPathForSelectedRow]; UITableViewCell *cell = [self.myTableView cellForRowAtIndexPath:indexPath]; NSLog(@"Selected Section %d and Row %d", indexPath.section, indexPath.row); //set the cell value from the date picker value and format it properly switch (indexPath.row) { case 0: cell.detailTextLabel.text = [self.dateFormatter1 stringFromDate:myDatePicker.date]; break; case 1: cell.detailTextLabel.text = [self.dateFormatter2 stringFromDate:myDatePicker.date]; break; case 2: cell.detailTextLabel.text = [self.dateFormatter3 stringFromDate:myDatePicker.date]; break; default: break; } //remove the date picker view form the super view [self.myDatePicker removeFromSuperview]; //deselect the current table row [self.myTableView deselectRowAtIndexPath:indexPath animated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
No comments:
Post a Comment
NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.