Monday, December 29, 2008

A Reusable Date Drill-Down Controller

The other day, I posted a reusable table-based drill-down controller. Today, I'm posting another in my series of re-usable drill-down controllers: a reusable date drill-down.

To use this controller, designed to be used as a drill-down in a Navigation-based App, all you have to do is create an instance of the class, and set that instance's delegate to self, and then set the date to be displayed when it is first shown, like so:

DateViewController *controller = [[DateViewController alloc] init];
controller.delegate = self;
controller.date = theDateToBeEdited;
[delegate.rootController pushViewController:controller animated:YES];
[controller release];

Then, implement this delegate method:

- (void)takeNewDate:(NSDate *)newDate
{
myObject.date = newDate;
}

Now, when the drill-down controller is dismissed, if the user pressed the Save button, that takeNewDate: method will get called with the new value, and all you have to do is stick the new date back into your data model. The controller class is self-contained, and there's no need to edit the controller class at all (though feel free to expand on it if you want). If you want to customize the appearance of the date picker, you can use the controller's datePicker property, for example, to change the date picker's mode:

controller.datePicker.datePickerMode = UIDatePickerModeDateAndTime;

Here's the date picker class:

DateViewController.h
/*
DateViewController.h
*/


#import <UIKit/UIKit.h>
#import "Person.h"

@protocol DateViewDelegate <NSObject>
@required
- (void)takeNewDate:(NSDate *)newDate;
- (UINavigationController *)navController; // Return the navigation controller
@end


@interface DateViewController : UIViewController {
UIDatePicker *datePicker;
NSDate *date;

id <DateViewDelegate> delegate; // weak ref
}
@property (nonatomic, retain) IBOutlet UIDatePicker *datePicker;
@property (nonatomic, retain) NSDate *date;
@property (nonatomic, assign) id <DateViewDelegate> delegate;
-(IBAction)dateChanged;
@end


DateViewController.m
/*
DateViewController.m
*/

#import "DateViewController.h"
#import "BirthdaysCategories.h"

@implementation DateViewController
@synthesize datePicker;
@synthesize date;
@synthesize delegate;

-(IBAction)dateChanged
{
self.date = [datePicker date];
}
-(IBAction)cancel
{
[[self.delegate navController] popViewControllerAnimated:YES];
}
-(IBAction)save
{
[self.delegate takeNewDate:date];
[[self.delegate navController] popViewControllerAnimated:YES];
}
- (void)loadView
{
UIView *theView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.view = theView;
[theView release];


UIDatePicker *theDatePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0.0, 206.0, 320.0, 216.0)];
self.datePicker = theDatePicker;
[theDatePicker release];
[datePicker addTarget:self action:@selector(dateChanged) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];


UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
initWithTitle:@"Cancel"
style:UIBarButtonItemStylePlain
target:self
action:@selector(cancel)]
;
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
initWithTitle:@"Save"
style:UIBarButtonItemStylePlain
target:self
action:@selector(save)]
;
self.navigationItem.rightBarButtonItem = saveButton;
[saveButton release];

self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];

}

- (void)viewWillAppear:(BOOL)animated
{
if (self.date != nil)
[self.datePicker setDate:date animated:YES];
else
[self.datePicker setDate:[NSDate date] animated:YES];

[super viewWillAppear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)dealloc {
[datePicker release];
[date release];
[super dealloc];
}
@end





5 comments:

Danilo Campos said...

Thanks for this -- exactly what I needed tonight.

One thing: if you're being conscious of localization, wouldn't it be better to use

formatter.dateStyle = NSDateFormatterLongStyle;

instead of manually defining the date format?

Awesome code -- thanks for sharing it.

Hiram Fernandez said...

I got a warning saying my controller class doesnt implement the DateViewDelete protocol

and that makes my app crash after I hit the save button/

any ideas?

jack chan said...

Louis Vuitton Aviator M40385
Louis Vuitton Aviator M40384
Louis Vuitton Aviator M40383
Louis Vuitton Mahina leather Stellar PM M93177
Louis Vuitton Mahina leather Stellar PM M93176
Louis Vuitton Mahina leather Stellar PM M93175
taiga leather
bum bag
louis vuitton totally
louis vuitton denim
Pochette
Stephen Sprouse
louis vuitton stephen sprouse
Monogram Vernis
LV Monogram Vernis

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels

Rich said...

Is anyone else getting delgate undeclarerd error in the parent view? I might have missed something??