mirror of
https://github.com/purplecabbage/phonegap-plugins.git
synced 2026-01-15 01:08:17 -05:00
339 lines
13 KiB
Objective-C
339 lines
13 KiB
Objective-C
//
|
|
// PickerView.m
|
|
//
|
|
// Created by Olivier Louvignes on 11/28/2011.
|
|
//
|
|
// Copyright 2011 Olivier Louvignes. All rights reserved.
|
|
// MIT Licensed
|
|
|
|
#import "PickerView.h"
|
|
|
|
// Private interface
|
|
@interface PickerView()
|
|
@property (nonatomic, retain) UIPickerView *pickerView;
|
|
@end
|
|
|
|
|
|
@implementation PickerView
|
|
|
|
@synthesize pickerView = _pickerView;
|
|
|
|
@synthesize callbackID;
|
|
@synthesize systemMajorVersion;
|
|
@synthesize actionSheet;
|
|
@synthesize popoverController;
|
|
@synthesize items;
|
|
|
|
-(void)create:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
|
{
|
|
|
|
//NSLog(@"PickerView::create():arguments: %@", arguments);
|
|
//NSLog(@"PickerView::create():options: %@", options);
|
|
|
|
// The first argument in the arguments parameter is the callbackID.
|
|
// We use this to send data back to the successCallback or failureCallback
|
|
// through PluginResult.
|
|
self.callbackID = [arguments pop];
|
|
self.systemMajorVersion = [[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue];
|
|
|
|
// Compiling options with defaults
|
|
NSString *title = [options objectForKey:@"title"] ?: @" ";
|
|
NSString *style = [options objectForKey:@"style"] ?: @"default";
|
|
NSString *doneButtonLabel = [options objectForKey:@"doneButtonLabel"] ?: @"Done";
|
|
NSString *cancelButtonLabel = [options objectForKey:@"cancelButtonLabel"] ?: @"Cancel";
|
|
|
|
// Hold slots items in an instance variable
|
|
self.items = [options objectForKey:@"items"];
|
|
|
|
// Initialize PickerView
|
|
self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 40.0f, 320.0f, 162.0f)];
|
|
self.pickerView.showsSelectionIndicator = YES;
|
|
self.pickerView.delegate = self;
|
|
|
|
// Loop through slots to define default value
|
|
for(int i = 0; i < [self.items count]; i++) {
|
|
NSDictionary *slot = [self.items objectAtIndex:i];
|
|
// Check for a default value
|
|
NSString *defaultValue = [NSString stringWithFormat:@"%@", [slot objectForKey:@"value"]];
|
|
if([slot objectForKey:@"data"] && defaultValue) {
|
|
// Loop through slot data
|
|
for(int j = 0; j < [[slot objectForKey:@"data"] count]; j++) {
|
|
NSDictionary *slotData = [[slot objectForKey:@"data"] objectAtIndex:j];
|
|
NSString *slotDataValue = [NSString stringWithFormat:@"%@", [slotData objectForKey:@"value"]];
|
|
// Check for a default value match
|
|
if([slotDataValue isEqualToString:defaultValue]) {
|
|
[self.pickerView selectRow:j inComponent:i animated:NO];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if device is iPad as we won't be able to use an ActionSheet there
|
|
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
|
return [self createForIpad:arguments withDict:options];
|
|
}
|
|
|
|
// Create actionSheet
|
|
self.actionSheet = [[UIActionSheet alloc] initWithTitle:title
|
|
delegate:self
|
|
cancelButtonTitle:nil
|
|
destructiveButtonTitle:nil
|
|
otherButtonTitles:nil];
|
|
|
|
// Style actionSheet, defaults to UIActionSheetStyleDefault
|
|
if([style isEqualToString:@"black-opaque"]) actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
|
|
else if([style isEqualToString:@"black-translucent"]) actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
|
|
else actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
|
|
|
|
// Append pickerView
|
|
[actionSheet addSubview:self.pickerView];
|
|
[self.pickerView release];
|
|
|
|
// Create segemented cancel button
|
|
UISegmentedControl *cancelButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:cancelButtonLabel]];
|
|
cancelButton.momentary = YES;
|
|
cancelButton.frame = CGRectMake(5.0f, 7.0f, 50.0f, 30.0f);
|
|
cancelButton.segmentedControlStyle = UISegmentedControlStyleBar;
|
|
cancelButton.tintColor = [UIColor blackColor];
|
|
[cancelButton addTarget:self action:@selector(segmentedControl:didDismissWithCancelButton:) forControlEvents:UIControlEventValueChanged];
|
|
// Append close button
|
|
[actionSheet addSubview:cancelButton];
|
|
[cancelButton release];
|
|
|
|
// Create segemented done button
|
|
UISegmentedControl *doneButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:doneButtonLabel]];
|
|
doneButton.momentary = YES;
|
|
doneButton.frame = CGRectMake(265.0f, 7.0f, 50.0f, 30.0f);
|
|
doneButton.segmentedControlStyle = UISegmentedControlStyleBar;
|
|
doneButton.tintColor = [UIColor colorWithRed:51.0f/255.0f green:102.0f/255.0f blue:153.0f/255.0f alpha:1.0f];
|
|
[doneButton addTarget:self action:@selector(segmentedControl:didDismissWithDoneButton:) forControlEvents:UIControlEventValueChanged];
|
|
// Append done button
|
|
[actionSheet addSubview:doneButton];
|
|
[doneButton release];
|
|
|
|
//[actionSheet sendSubviewToBack:pickerView];
|
|
|
|
// Toggle ActionSheet
|
|
[actionSheet showInView:self.webView.superview];
|
|
|
|
// Resize actionSheet was 360
|
|
float actionSheetHeight;
|
|
if(systemMajorVersion == 5) {
|
|
actionSheetHeight = 360.0f;
|
|
} else {
|
|
actionSheetHeight = 472.0f;
|
|
}
|
|
[actionSheet setBounds:CGRectMake(0, 0, 320.0f, actionSheetHeight)];
|
|
|
|
}
|
|
|
|
-(void)createForIpad:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
|
{
|
|
|
|
NSString *doneButtonLabel = [options objectForKey:@"doneButtonLabel"] ?: @"Done";
|
|
NSString *cancelButtonLabel = [options objectForKey:@"cancelButtonLabel"] ?: @"Cancel";
|
|
|
|
// Create a generic content view controller
|
|
UINavigationController* popoverContent = [[UINavigationController alloc] init];
|
|
// Create a generic container view
|
|
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320.0f, 162.0f)];
|
|
popoverContent.view = popoverView;
|
|
|
|
// Append pickerView
|
|
[popoverView addSubview:self.pickerView];
|
|
[self.pickerView release];
|
|
|
|
/*
|
|
UIBarButtonItem *okButton = [[UIBarButtonItem alloc] initWithTitle:@"Ok" style:UIBarButtonItemStyleBordered target:self action:@selector(okayButtonPressed)];
|
|
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelButtonPressed)];
|
|
|
|
[popoverContent.navigationItem setLeftBarButtonItem:cancelButton animated:NO];
|
|
[popoverContent.navigationItem setRightBarButtonItem:okButton animated:NO];
|
|
popoverContent.topViewController.navigationItem.title = @"MY TITLE!";
|
|
popoverContent.navigationItem.title = @"MY TITLE!";
|
|
*/
|
|
|
|
// Create segemented cancel button
|
|
UISegmentedControl *cancelButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:cancelButtonLabel]];
|
|
cancelButton.momentary = YES;
|
|
cancelButton.frame = CGRectMake(5.0f, 7.0f, 50.0f, 30.0f);
|
|
cancelButton.segmentedControlStyle = UISegmentedControlStyleBar;
|
|
cancelButton.tintColor = [UIColor blackColor];
|
|
[cancelButton addTarget:self action:@selector(segmentedControl:didDismissWithCancelButton:) forControlEvents:UIControlEventValueChanged];
|
|
// Append close button
|
|
[popoverView addSubview:cancelButton];
|
|
[cancelButton release];
|
|
|
|
// Create segemented done button
|
|
UISegmentedControl *doneButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:doneButtonLabel]];
|
|
doneButton.momentary = YES;
|
|
doneButton.frame = CGRectMake(265.0f, 7.0f, 50.0f, 30.0f);
|
|
doneButton.segmentedControlStyle = UISegmentedControlStyleBar;
|
|
doneButton.tintColor = [UIColor colorWithRed:51.0f/255.0f green:102.0f/255.0f blue:153.0f/255.0f alpha:1.0f];
|
|
[doneButton addTarget:self action:@selector(segmentedControl:didDismissWithDoneButton:) forControlEvents:UIControlEventValueChanged];
|
|
// Append done button
|
|
[popoverView addSubview:doneButton];
|
|
[doneButton release];
|
|
|
|
// Resize the popover view shown
|
|
// in the current view to the view's size
|
|
popoverContent.contentSizeForViewInPopover = CGSizeMake(320.0f, 162.0f);
|
|
|
|
// Create a popover controller
|
|
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
|
|
popoverController.delegate = self;
|
|
|
|
//present the popover view non-modal with a
|
|
//refrence to the button pressed within the current view
|
|
[popoverController presentPopoverFromRect:CGRectMake(374.0f, 1014.0f, 20.0f, 20.0f)
|
|
inView:self.webView.superview
|
|
permittedArrowDirections:UIPopoverArrowDirectionAny
|
|
animated:YES];
|
|
|
|
//release the popover content
|
|
[popoverView release];
|
|
[popoverContent release];
|
|
|
|
}
|
|
|
|
//
|
|
// Dismiss methods
|
|
//
|
|
|
|
// Picker with segmentedControls dismissed with done
|
|
- (void)segmentedControl:(UISegmentedControl *)segmentedControl didDismissWithDoneButton:(NSInteger)buttonIndex
|
|
{
|
|
//NSLog(@"didDismissWithDoneButton:%d", buttonIndex);
|
|
|
|
// Check if device is iPad
|
|
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
|
// Emulate a new delegate method
|
|
[self popoverController:popoverController dismissWithClickedButtonIndex:1 animated:YES];
|
|
} else {
|
|
[actionSheet dismissWithClickedButtonIndex:1 animated:YES];
|
|
}
|
|
}
|
|
|
|
// Picker with segmentedControls dismissed with cancel
|
|
- (void)segmentedControl:(UISegmentedControl *)segmentedControl didDismissWithCancelButton:(NSInteger)buttonIndex
|
|
{
|
|
//NSLog(@"didDismissWithCancelButton:%d", buttonIndex);
|
|
|
|
// Check if device is iPad
|
|
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
|
// Emulate a new delegate method
|
|
[self popoverController:popoverController dismissWithClickedButtonIndex:0 animated:YES];
|
|
} else {
|
|
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
|
|
}
|
|
}
|
|
|
|
// Popover generic dismiss - iPad
|
|
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
|
|
{
|
|
//NSLog(@"popoverControllerDidDismissPopover");
|
|
|
|
// Retreive pickerView
|
|
NSArray *subviews = [self.popoverController.contentViewController.view subviews];
|
|
UIPickerView *pickerView = [subviews objectAtIndex:0];
|
|
// Simulate a cancel click
|
|
[self sendResultsFromPickerView:pickerView withButtonIndex:0];
|
|
}
|
|
|
|
// Popover emulated button-powered dismiss - iPad
|
|
- (void)popoverController:(UIPopoverController *)popoverController dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(Boolean)animated
|
|
{
|
|
//NSLog(@"didDismissPopoverWithButtonIndex:%d", buttonIndex);
|
|
|
|
// Manually dismiss the popover
|
|
[self.popoverController dismissPopoverAnimated:animated];
|
|
// Retreive pickerView
|
|
NSArray *subviews = [self.popoverController.contentViewController.view subviews];
|
|
UIPickerView *pickerView = [subviews objectAtIndex:0];
|
|
[self sendResultsFromPickerView:pickerView withButtonIndex:buttonIndex];
|
|
|
|
// Release objects
|
|
[self.popoverController release];
|
|
}
|
|
|
|
// ActionSheet generic dismiss - iPhone
|
|
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
|
|
{
|
|
//NSLog(@"didDismissWithButtonIndex:%d", buttonIndex);
|
|
|
|
// Retreive pickerView
|
|
NSArray *subviews = [self.actionSheet subviews];
|
|
UIPickerView *pickerView = [subviews objectAtIndex:1];
|
|
[self sendResultsFromPickerView:pickerView withButtonIndex:buttonIndex];
|
|
|
|
// Release objects
|
|
[self.actionSheet release];
|
|
}
|
|
|
|
//
|
|
// Results
|
|
//
|
|
|
|
- (void)sendResultsFromPickerView:(UIPickerView *)pickerView withButtonIndex:(NSInteger)buttonIndex {
|
|
|
|
// Build returned result
|
|
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
|
|
NSMutableDictionary *values = [[NSMutableDictionary alloc] init];
|
|
|
|
// Loop throught slots
|
|
for(int i = 0; i < [items count]; i++) {
|
|
NSInteger selectedRow = [pickerView selectedRowInComponent:i];
|
|
NSString *selectedValue = [[[[items objectAtIndex:i] objectForKey:@"data"] objectAtIndex:selectedRow] objectForKey:@"value"];
|
|
NSString *slotName = [[items objectAtIndex:i] objectForKey:@"name"] ?: [NSString stringWithFormat:@"%d", i];
|
|
[values setObject:selectedValue forKey:slotName];
|
|
}
|
|
|
|
[result setObject:[NSNumber numberWithInteger:buttonIndex] forKey:@"buttonIndex"];
|
|
[result setObject:values forKey:@"values"];
|
|
|
|
// Create Plugin Result
|
|
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:result];
|
|
|
|
// Checking if cancel was clicked
|
|
if (buttonIndex == 0) {
|
|
//Call the Failure Javascript function
|
|
[self writeJavascript: [pluginResult toErrorCallbackString:self.callbackID]];
|
|
}else {
|
|
//Call the Success Javascript function
|
|
[self writeJavascript: [pluginResult toSuccessCallbackString:self.callbackID]];
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Picker delegate
|
|
//
|
|
|
|
|
|
// Listen picker selected row
|
|
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
|
|
//NSLog(@"didSelectRow %d", row);
|
|
}
|
|
|
|
// Tell the picker how many rows are available for a given component
|
|
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
|
|
return [[[items objectAtIndex:component] objectForKey:@"data"] count];
|
|
}
|
|
|
|
// Tell the picker how many components it will have
|
|
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
|
|
return [items count];
|
|
}
|
|
|
|
// Tell the picker the title for a given component
|
|
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
|
|
//NSLog(@"%d:%d", component, row);
|
|
return [[[[items objectAtIndex:component] objectForKey:@"data"] objectAtIndex:row] objectForKey:@"text"];
|
|
}
|
|
|
|
// Tell the picker the width of each row for a given component
|
|
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
|
|
return 300.0f/[items count];
|
|
}
|
|
|
|
@end |