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.