Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 418 lines (348 sloc) 15.6 KB
//
// ActionSheetPicker.m
// Spent
//
// Created by Tim Cinel on 3/01/11.
// Copyright 2011 Thunderous Playground. All rights reserved.
//
#import "ActionSheetPicker.h"
@implementation ActionSheetPicker
@synthesize view = _view;
@synthesize data = _data;
@synthesize selectedIndex = _selectedIndex;
@synthesize title = _title;
@synthesize selectedDate = _selectedDate;
@synthesize datePickerMode = _datePickerMode;
@synthesize bigUnitString = _bigUnitString;
@synthesize bigUnitMax = _bigUnitMax;
@synthesize bigUnitDigits = _bigUnitDigits;
@synthesize selectedBigUnit = _selectedBigUnit;
@synthesize smallUnitString = _smallUnitString;
@synthesize smallUnitMax = _smallUnitMax;
@synthesize smallUnitDigits = _smallUnitDigits;
@synthesize selectedSmallUnit = _selectedSmallUnit;
@synthesize target = _target;
@synthesize action = _action;
@synthesize actionSheet = _actionSheet;
@synthesize popOverController = _popOverController;
@synthesize pickerView = _pickerView;
@synthesize datePickerView = _datePickerView;
@synthesize distancePickerView = _distancePickerView;
@synthesize pickerPosition = _pickerPosition;
@dynamic viewSize;
#pragma mark -
#pragma mark NSObject
+ (void)displayActionPickerWithView:(UIView *)aView data:(NSArray *)data selectedIndex:(NSInteger)selectedIndex target:(id)target action:(SEL)action title:(NSString *)title {
ActionSheetPicker *actionSheetPicker = [[ActionSheetPicker alloc] initForDataWithContainingView:aView data:data selectedIndex:selectedIndex target:target action:action title:title];
[actionSheetPicker showActionPicker];
[actionSheetPicker release];
}
+ (void)displayActionPickerWithView:(UIView *)aView datePickerMode:(UIDatePickerMode)datePickerMode selectedDate:(NSDate *)selectedDate target:(id)target action:(SEL)action title:(NSString *)title {
ActionSheetPicker *actionSheetPicker = [[ActionSheetPicker alloc] initForDateWithContainingView:aView datePickerMode:datePickerMode selectedDate:selectedDate target:target action:action title:title];
[actionSheetPicker showActionPicker];
[actionSheetPicker release];
}
+ (void)displayActionPickerWithView:(UIView *)aView
bigUnitString:(NSString *)bigUnitString
bigUnitMax:(NSInteger)bigUnitMax
selectedBigUnit:(NSInteger)selectedBigUnit
smallUnitString:(NSString*)smallUnitString
smallUnitMax:(NSInteger)smallUnitMax
selectedSmallUnit:(NSInteger)selectedSmallUnit
target:(id)target
action:(SEL)action
title:(NSString*)title {
ActionSheetPicker *actionSheetPicker = [[ActionSheetPicker alloc] initForMeasurementWithContainingView:aView bigUnitString:bigUnitString bigUnitMax:bigUnitMax selectedBigUnit:selectedBigUnit smallUnitString:smallUnitString smallUnitMax:smallUnitMax selectedSmallUnit:selectedSmallUnit target:target action:action title:title];
[actionSheetPicker showActionPicker];
[actionSheetPicker release];
}
- (id)initWithContainingView:(UIView *)aView target:(id)target action:(SEL)action {
if ((self = [super init]) != nil) {
self.view = aView;
self.target = target;
self.action = action;
}
return self;
}
- (id)initForDataWithContainingView:(UIView *)aView data:(NSArray *)data selectedIndex:(NSInteger)selectedIndex target:(id)target action:(SEL)action title:(NSString *)title {
if ([self initWithContainingView:aView target:target action:action] != nil) {
self.data = data;
self.selectedIndex = selectedIndex;
self.title = title;
_isMeasurement = NO;
}
return self;
}
- (id)initForDateWithContainingView:(UIView *)aView datePickerMode:(UIDatePickerMode)datePickerMode selectedDate:(NSDate *)selectedDate target:(id)target action:(SEL)action title:(NSString *)title {
if ([self initWithContainingView:aView target:target action:action] != nil) {
self.datePickerMode = datePickerMode;
self.selectedDate = selectedDate;
self.title = title;
_isMeasurement = NO;
}
return self;
}
- (id)initForMeasurementWithContainingView:(UIView *)aView
bigUnitString:(NSString *)bigUnitString
bigUnitMax:(NSInteger)bigUnitMax
selectedBigUnit:(NSInteger)selectedBigUnit
smallUnitString:(NSString*)smallUnitString
smallUnitMax:(NSInteger)smallUnitMax
selectedSmallUnit:(NSInteger)selectedSmallUnit
target:(id)target
action:(SEL)action
title:(NSString*)title {
if ([self initWithContainingView:aView target:target action:action] != nil) {
self.bigUnitString = bigUnitString;
self.bigUnitMax = bigUnitMax;
self.selectedBigUnit = selectedBigUnit;
self.smallUnitString = smallUnitString;
self.smallUnitMax = smallUnitMax;
self.selectedSmallUnit = selectedSmallUnit;
self.title = title;
_isMeasurement = YES;
self.bigUnitDigits = [[NSString stringWithFormat:@"%i", self.bigUnitMax] length];
self.smallUnitDigits = [[NSString stringWithFormat:@"%i", self.smallUnitMax] length];
}
return self;
}
#pragma mark -
#pragma mark Implementation
- (void)showActionPicker {
[self retain];
//create the new view
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.viewSize.width, 260)] autorelease];
if (nil != self.data) {
//show data picker
[self showDataPicker];
[view addSubview:self.pickerView];
} else if (_isMeasurement) {
[self showDistancePicker];
[view addSubview:self.distancePickerView];
} else {
//show date picker
[self showDatePicker];
[view addSubview:self.datePickerView];
}
CGRect frame = CGRectMake(0, 0, self.viewSize.width, 44);
UIToolbar *pickerDateToolbar = [[UIToolbar alloc] initWithFrame:frame];
pickerDateToolbar.barStyle = UIBarStyleBlackOpaque;
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(actionPickerCancel)];
[barItems addObject:cancelBtn];
[cancelBtn release];
UIBarButtonItem *flexSpace = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil] autorelease];
[barItems addObject:flexSpace];
//Add tool bar title label
if (nil != self.title){
UILabel *toolBarItemlabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 180,30)];
[toolBarItemlabel setTextAlignment:UITextAlignmentCenter];
[toolBarItemlabel setTextColor:[UIColor whiteColor]];
[toolBarItemlabel setFont:[UIFont boldSystemFontOfSize:16]];
[toolBarItemlabel setBackgroundColor:[UIColor clearColor]];
toolBarItemlabel.text = self.title;
UIBarButtonItem *buttonLabel =[[UIBarButtonItem alloc]initWithCustomView:toolBarItemlabel];
[toolBarItemlabel release];
[barItems addObject:buttonLabel];
[buttonLabel release];
[barItems addObject:flexSpace];
}
//add "Done" button
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(actionPickerDone)];
[barItems addObject:barButton];
[barButton release];
[pickerDateToolbar setItems:barItems animated:YES];
[barItems release];
[view addSubview:pickerDateToolbar];
[pickerDateToolbar release];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
//spawn popovercontroller
UIViewController *viewController = [[[UIViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController.view = view;
viewController.contentSizeForViewInPopover = viewController.view.frame.size;
_popOverController = [[UIPopoverController alloc] initWithContentViewController:viewController];
[self.popOverController presentPopoverFromRect:self.view.frame inView:self.view.superview?:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
//spawn actionsheet
_actionSheet = [[UIActionSheet alloc] initWithTitle:[self isViewPortrait]?nil:@"\n\n\n" delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[self.actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
[self.actionSheet addSubview:view];
[self.actionSheet showInView:self.view];
self.actionSheet.bounds = CGRectMake(0, 0, self.viewSize.width, self.viewSize.height+5);
}
}
- (void)showDataPicker {
//spawn pickerview
CGRect pickerFrame = CGRectMake(0, 40, self.viewSize.width, 216);
_pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
self.pickerView.showsSelectionIndicator = YES;
[self.pickerView selectRow:self.selectedIndex inComponent:0 animated:NO];
}
- (void)showDatePicker {
//spawn datepickerview
CGRect datePickerFrame = CGRectMake(0, 40, self.viewSize.width, 216);
_datePickerView = [[UIDatePicker alloc] initWithFrame:datePickerFrame];
self.datePickerView.datePickerMode = self.datePickerMode;
[self.datePickerView setDate:self.selectedDate animated:NO];
[self.datePickerView addTarget:self action:@selector(eventForDatePicker:) forControlEvents:UIControlEventValueChanged];
}
- (void)showDistancePicker {
//spawn distancepickerview
CGRect distancePickerFrame = CGRectMake(0, 40, self.viewSize.width, 216);
_distancePickerView = [[DistancePickerView alloc] initWithFrame:distancePickerFrame];
self.distancePickerView.delegate = self;
self.distancePickerView.dataSource = self;
self.distancePickerView.showsSelectionIndicator = YES;
[self.distancePickerView addLabel:self.bigUnitString forComponent:(self.bigUnitDigits - 1)
forLongestString:nil];
[self.distancePickerView addLabel:self.smallUnitString forComponent:(self.bigUnitDigits + self.smallUnitDigits - 1) forLongestString:nil];
NSInteger unitSubtract = 0;
NSInteger currentDigit = 0;
for (int i = 0; i < self.bigUnitDigits; ++i) {
NSInteger factor = (int)pow((double)10, (double)(self.bigUnitDigits - (i+1)));
currentDigit = (( self.selectedBigUnit - unitSubtract ) / factor ) ;
[self.distancePickerView selectRow:currentDigit inComponent:i animated:NO];
unitSubtract += currentDigit * factor;
}
unitSubtract = 0;
currentDigit = 0;
for (int i = self.bigUnitDigits; i < self.bigUnitDigits + self.smallUnitDigits; ++i) {
NSInteger factor = (int)pow((double)10, (double)(self.bigUnitDigits + self.smallUnitDigits - (i+1)));
currentDigit = (( self.selectedSmallUnit - unitSubtract ) / factor ) ;
[self.distancePickerView selectRow:currentDigit inComponent:i animated:NO];
unitSubtract += currentDigit * factor;
}
}
- (void)actionPickerDone {
if (self.actionSheet) {
[self.actionSheet dismissWithClickedButtonIndex:0 animated:YES];
} else {
[self.popOverController dismissPopoverAnimated:YES];
}
if (nil != self.data) {
//send data picker message
[self.target performSelector:self.action withObject:[NSNumber numberWithInt:self.selectedIndex] withObject:self.view];
} else if (_isMeasurement) {
//send measurement picker message
NSInteger bigUnits = 0;
NSInteger smallUnits = 0;
for (int i = 0; i < self.bigUnitDigits; ++i) {
bigUnits += [self.distancePickerView selectedRowInComponent:i] * (int)pow((double)10, (double)(self.bigUnitDigits - (i + 1)));
}
for (int i = self.bigUnitDigits; i < self.bigUnitDigits + self.smallUnitDigits; ++i) {
smallUnits += [self.distancePickerView selectedRowInComponent:i] * (int)pow((double)10, (double)((self.distancePickerView.numberOfComponents - i - 1)));
}
//sending three objects, so no performSelector:
objc_msgSend(self.target, self.action, [NSNumber numberWithInt:bigUnits], [NSNumber numberWithInt:smallUnits], self.view);
} else {
//send date picker message
[self.target performSelector:self.action withObject:self.selectedDate withObject:self.view];
}
[self release];
}
- (void)actionPickerCancel {
if (self.actionSheet) {
[self.actionSheet dismissWithClickedButtonIndex:0 animated:YES];
} else {
[self.popOverController dismissPopoverAnimated:YES];
}
[self release];
}
- (BOOL) isViewPortrait {
return UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
}
- (CGSize) viewSize {
CGSize size = CGSizeMake(320, 480);
if (![self isViewPortrait]) {
size = CGSizeMake(480, 320);
}
return size;
}
#pragma mark -
#pragma mark Callbacks
- (void)eventForDatePicker:(id)sender {
UIDatePicker *datePicker = (UIDatePicker *)sender;
self.selectedDate = datePicker.date;
}
#pragma mark -
#pragma mark UIPickerViewDelegate
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.selectedIndex = row;
}
#pragma mark -
#pragma mark UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
if (_isMeasurement) {
return self.bigUnitDigits + self.smallUnitDigits;
} else {
return 1;
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (_isMeasurement) {
if (component + 1 <= self.bigUnitDigits) {
if (component == 0) {
return self.bigUnitMax / (int)pow((double)10, (double)(self.bigUnitDigits - 1)) + 1;
} else {
return 10;
}
} else {
if (component == self.bigUnitDigits) {
return self.smallUnitMax / (int)pow((double)10, (double)(self.smallUnitDigits - 1)) + 1;
} else {
return 10;
}
}
} else {
return self.data.count;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (_isMeasurement) {
return [NSString stringWithFormat:@"%i", row];
} else {
return [self.data objectAtIndex:row];
}
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
CGFloat totalWidth = pickerView.frame.size.width - 30;
if (_isMeasurement) {
CGFloat bigUnitLabelSize = [self.bigUnitString sizeWithFont:[UIFont boldSystemFontOfSize:20]].width;
CGFloat smallUnitLabelSize = [self.smallUnitString sizeWithFont:[UIFont boldSystemFontOfSize:20]].width;
CGFloat otherSize = (totalWidth - bigUnitLabelSize - smallUnitLabelSize)/(self.bigUnitDigits + self.smallUnitDigits);
if (component == self.bigUnitDigits - 1) {
return otherSize + bigUnitLabelSize;
} else if (component == self.bigUnitDigits + self.smallUnitDigits - 1) {
return otherSize + smallUnitLabelSize;
} else {
return otherSize;
}
} else {
return totalWidth;
}
}
#pragma mark -
#pragma mark Memory Management
- (void)dealloc {
// NSLog(@"ActionSheet Dealloc");
self.actionSheet = nil;
self.popOverController = nil;
self.data = nil;
self.pickerView.delegate = nil;
self.pickerView.dataSource = nil;
self.pickerView = nil;
self.distancePickerView.delegate = nil;
self.distancePickerView.dataSource = nil;
self.distancePickerView = nil;
self.smallUnitString = nil;
self.bigUnitString = nil;
[self.datePickerView removeTarget:self action:@selector(eventForDatePicker:) forControlEvents:UIControlEventValueChanged];
self.datePickerView = nil;
self.selectedDate = nil;
self.view = nil;
self.target = nil;
[super dealloc];
}
@end