// // UIViewControllerDateRangeEditor.m // UIViewControllerDateRangeEditor // #import "UIViewControllerDateRangeEditor.h" @interface UIViewControllerDateRangeEditor ( PrivateMethods ) - (NSDateFormatter*) createDateFormatter; - (NSTimeInterval) limitTimeInterval:(NSTimeInterval)_timeValue; - (NSString*) stringFromDateTimeInterval:(NSTimeInterval)_interval; - (void) selectButtonHold:(id)sender; @end @implementation UIViewControllerDateRangeEditor #pragma mark --------------------------------------------------------- #pragma mark === Properties === #pragma mark --------------------------------------------------------- -(NSTimeInterval) startTimeInterval { return startTimeInterval; } - (void) setStartTimeInterval:(NSTimeInterval)_timeValue { startTimeInterval = _timeValue; // setup the display [startDate setText:[self stringFromDateTimeInterval:startTimeInterval]]; } -(NSTimeInterval) endTimeInterval { return endTimeInterval; } - (void) setEndTimeInterval:(NSTimeInterval)_timeValue { endTimeInterval = _timeValue; // setup the display [endDate setText:[self stringFromDateTimeInterval:endTimeInterval]]; } @synthesize minTimeInterval; @synthesize maxTimeInterval; @synthesize savePressed; #pragma mark --------------------------------------------------------- #pragma mark === End Properties === #pragma mark --------------------------------------------------------- #pragma mark --------------------------------------------------------- #pragma mark === Constructor / Destructor Functions === #pragma mark --------------------------------------------------------- // ------------------------------------------------------------------- // Initialisation // ------------------------------------------------------------------- - (id)initWithCoder:(NSCoder*)coder { if (self = [super initWithCoder:coder]) { dateFormatter = [self createDateFormatter]; [self reset]; } return self; } // ------------------------------------------------------------------- // Initialisation // ------------------------------------------------------------------- - (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { dateFormatter = [self createDateFormatter]; [self reset]; } return self; } // ------------------------------------------------------------------- // dealloc // ------------------------------------------------------------------- - (void) dealloc { [leftBarButton release]; [rightBarButton release]; [startLabel release]; [startDate release]; [endLabel release]; [endDate release]; [buttonStart release]; [buttonSelected release]; [buttonImage release]; [datePicker release]; [normalColor release]; [highlightColor release]; [dateFormatter release]; [super dealloc]; } #pragma mark --------------------------------------------------------- #pragma mark === End Constructor / Destructor Functions === #pragma mark --------------------------------------------------------- #pragma mark --------------------------------------------------------- #pragma mark === View Functions === #pragma mark --------------------------------------------------------- // ------------------------------------------------------------------- // view did load // ------------------------------------------------------------------- - (void) viewDidLoad { [super viewDidLoad]; // Setup the navigation bar self.navigationItem.leftBarButtonItem = leftBarButton; self.navigationItem.rightBarButtonItem = rightBarButton; // grab the start date colors if ( normalColor == nil ) normalColor = [[startDate textColor] retain]; if ( highlightColor == nil ) highlightColor = [[startDate highlightedTextColor] retain]; } // ------------------------------------------------------------------- // view is about to appear // ------------------------------------------------------------------- - (void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // save has not been pressed savePressed = FALSE; // limit the start and end dates to be within the min and max values self.startTimeInterval = [self limitTimeInterval:self.startTimeInterval]; self.endTimeInterval = [self limitTimeInterval:self.endTimeInterval]; // set the date in the picker [datePicker setDate:[NSDate dateWithTimeIntervalSince1970:startTimeInterval] animated:FALSE]; // always start editing the start date [self selectStartDate:buttonStart]; // set the min and max date values [datePicker setMinimumDate:[NSDate dateWithTimeIntervalSince1970:minTimeInterval]]; [datePicker setMaximumDate:[NSDate dateWithTimeIntervalSince1970:maxTimeInterval]]; } // ------------------------------------------------------------------- // view is did to disappear // ------------------------------------------------------------------- - (void) viewDidDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if ( delayReset ) { [self reset]; } // ---------------------------------------------- // reset the button back to it's normal state. // ---------------------------------------------- [buttonSelected setBackgroundImage:buttonImage forState:UIControlStateNormal]; [buttonSelected setSelected:FALSE]; [buttonImage release]; [buttonSelected release]; buttonImage = nil; buttonSelected = nil; // ---------------------------------------------- } #pragma mark --------------------------------------------------------- #pragma mark === View Functions === #pragma mark --------------------------------------------------------- #pragma mark --------------------------------------------------------- #pragma mark === Public Functions === #pragma mark --------------------------------------------------------- // ------------------------------------------------------------------- // reset the date value to the current date // ------------------------------------------------------------------- - (void) reset { if ( [self.view superview] ) { delayReset = TRUE; } else { savePressed = FALSE; editingStartDate = TRUE; self.startTimeInterval = [[NSDate date] timeIntervalSince1970]; self.endTimeInterval = [[NSDate date] timeIntervalSince1970] + ( 60 * 60 * 48 ); // add 48 hours self.minTimeInterval = [[NSDate distantPast] timeIntervalSince1970]; self.maxTimeInterval = [[NSDate distantFuture] timeIntervalSince1970]; } } // ------------------------------------------------------------------- // cancel button has been pressed // ------------------------------------------------------------------- - (IBAction) cancel:(id)sender { // cancel edits if ( [self.navigationController.viewControllers count] > 1 ) { [self.navigationController popViewControllerAnimated:YES]; } else { [self.navigationController dismissModalViewControllerAnimated:YES]; } } // ------------------------------------------------------------------- // save button has been pressed // ------------------------------------------------------------------- - (IBAction)save:(id)sender { // is the date range unacceptiable if ( startTimeInterval > endTimeInterval ) { NSString * titleString = @"Problem!"; NSString * messageString = @"Choose an end date that is after the start date please."; NSString * buttonString = @"OK"; UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:titleString message:messageString delegate:nil cancelButtonTitle:buttonString otherButtonTitles:nil]; [alertView show]; [alertView release]; } else { // save has been pressed savePressed = TRUE; [self cancel:sender]; } } // ------------------------------------------------------------------- // date picker value has changed // ------------------------------------------------------------------- - (IBAction) dateChanged:(id)sender { NSTimeInterval newTimeInterval = [datePicker.date timeIntervalSince1970]; if ( editingStartDate ) { self.startTimeInterval = newTimeInterval; } else { self.endTimeInterval = newTimeInterval; } // indicate that there is an error if ( startTimeInterval > endTimeInterval ) { [startDate setTextColor:[UIColor redColor]]; [startDate setHighlightedTextColor:[UIColor redColor]]; } else { [startDate setTextColor:normalColor]; [startDate setHighlightedTextColor:highlightColor]; } } // ------------------------------------------------------------------- // select the start date // ------------------------------------------------------------------- - (IBAction) selectStartDate:(id)sender { [self selectButtonHold:sender]; editingStartDate = TRUE; [datePicker setDate:[NSDate dateWithTimeIntervalSince1970:startTimeInterval] animated:TRUE]; [startLabel setHighlighted:TRUE]; [startDate setHighlighted:TRUE]; [endLabel setHighlighted:FALSE]; [endDate setHighlighted:FALSE]; } // ------------------------------------------------------------------- // select the end date // ------------------------------------------------------------------- - (IBAction) selectEndDate:(id)sender { [self selectButtonHold:sender]; editingStartDate = FALSE; [datePicker setDate:[NSDate dateWithTimeIntervalSince1970:endTimeInterval] animated:TRUE]; [startLabel setHighlighted:FALSE]; [startDate setHighlighted:FALSE]; [endLabel setHighlighted:TRUE]; [endDate setHighlighted:TRUE]; } #pragma mark --------------------------------------------------------- #pragma mark === End Public Functions === #pragma mark --------------------------------------------------------- #pragma mark --------------------------------------------------------- #pragma mark === Privte Functions === #pragma mark --------------------------------------------------------- // ------------------------------------------------------------------- // create the date formatter // ------------------------------------------------------------------- - (NSDateFormatter*) createDateFormatter { NSDateFormatter * formatter = [[NSDateFormatter alloc] init]; // set the fromatter to be medium style “Nov 23, 1937” [formatter setDateStyle:NSDateFormatterMediumStyle]; [formatter setTimeStyle:NSDateFormatterShortStyle]; // set the formatter to provide a localized version. // “Nov 23, 1937” US to UK would be “23 Nov, 1937” [formatter setLocale:[NSLocale currentLocale]]; return formatter; } // ------------------------------------------------------------------- // limit the time interval // ------------------------------------------------------------------- - (NSTimeInterval) limitTimeInterval:(NSTimeInterval)_timeValue { if ( _timeValue < minTimeInterval ) { _timeValue = minTimeInterval; } else if ( _timeValue > maxTimeInterval ) { _timeValue = maxTimeInterval; } return _timeValue; } // ------------------------------------------------------------------- // Convert a Time interval to a date string // ------------------------------------------------------------------- - (NSString*) stringFromDateTimeInterval:(NSTimeInterval)_interval { NSDate * date = [NSDate dateWithTimeIntervalSince1970:_interval]; if ( ( [date compare:[NSDate distantPast]] != NSOrderedSame ) && ( [date compare:[NSDate distantFuture]] != NSOrderedSame ) ) { return [dateFormatter stringFromDate:date]; } return nil; } // ------------------------------------------------------------------- // select and hold the button so it looks like it's highlighted // ------------------------------------------------------------------- - (void) selectButtonHold:(id)sender { // This will grab the highlight image and // replace the normal image so the button // looks like it's still on. // // Note : you can use the Selected property // but it sometimes flickers. if ( [sender isKindOfClass:[UIButton class]] ) { // ---------------------------------------------- // reset the button back to it's normal state. // ---------------------------------------------- [buttonSelected setBackgroundImage:buttonImage forState:UIControlStateNormal]; [buttonSelected setSelected:FALSE]; [buttonImage release]; [buttonSelected release]; // ---------------------------------------------- // ---------------------------------------------- // update the next button state // ---------------------------------------------- buttonSelected = [sender retain]; buttonImage = [[buttonSelected backgroundImageForState:UIControlStateNormal] retain]; [buttonSelected setBackgroundImage:[buttonSelected backgroundImageForState:UIControlStateHighlighted] forState:UIControlStateNormal]; [buttonSelected setSelected:TRUE]; // ---------------------------------------------- } } #pragma mark --------------------------------------------------------- #pragma mark === End Privte Functions === #pragma mark --------------------------------------------------------- @end