この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 ActionSheetPickerとは
ActionSheetPickerとは、名前の通り、ActionSheet + Picker です。 これを使用すると、簡単に、PickerViewを載せたActionSheetが利用できます。
これは、個人的な感想ですが・・・ UIDatePickerなどで、項目を選択した後の取り扱い(選択を決定するためにOKが押したいなど)で、ちょっと悩むことがあります。 これに対して、アクションシートの中に入れてしまうことで、UIがハッキリするように感じています。
ActionSheetPicker-3.0は、BSDライセンスで公開されており、CocoaPodで簡単にインストールが可能です。
pod 'ActionSheetPicker-3.0', '~> 2.0.5'
なお、2016年2月現在の最新バージョンは2.0.5です。
ライブラリの導入後は、下記のインポートで利用可能になります。
#import "ActionSheetPicker.h"
2 UIActionSheetとUIAlertController
UIActionSheetがiOS8からdeprecatedとなり、UIAlertControllerの利用が推奨されていますが、もし、iOS7へも対応するとなると、両方を切り替える処理などが必要になります。しかし、ActionSheetPickerを使用する限り、これを気にする必要はありません。
ちなみに、ActionSheetPickerでは、どちらも使用しておらず、UIViewからのカスタムビューとなっています。
次のコードは、ActionSheetPicker-3.0/AbstractActionSheetPicker.mからの抜粋です。
- (void)showActionSheetPicker {
// メインビュー
UIView *masterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.viewSize.width, 260)];
//・・・・
// ツールバー追加
self.toolbar = [self createPickerToolbarWithTitle:self.title];
[masterView addSubview:self.toolbar];
//・・・・
// ピッカービューの追加
self.pickerView = [self configuredPickerView];
[masterView addSubview:_pickerView];
//・・・・
}
3 使用方法
ビューの種類によって、色々パラメータは変わりますが、使用方法としては大きく次の3種類になります。
(1) クラスメソッドを使用する方法
クラスメソッドを使用して、オブジェクトを生成することなくそのまま使用します。 一般的に、最も軽易な利用方法になります。
この場合、ボタンを押した際の処理などは、別のメソッドを用意して、そのメソッドを保持するクラス及びメソッド名を指定する事になります。
NSArray *items = @[@"001", @"002", @"003", @"..."];
int index;
[ActionSheetStringPicker showPickerWithTitle:@"Title"
rows:items
initialSelection:index
target:self // コールバックメソッドを保持するクラス
successAction:@selector(doneSelected:element:) // コールバックメソッド
cancelAction:@selector(cancellSelected:) origin:sender]; // コールバックメソッド
コールバック先のメソッドは、次のようになります。
- (void)doneSelected:(NSNumber *)selectedIndex element:(id)element {
NSLog([NSString stringWithFormat:@"%@",selectedIndex]);
}
- (void)cancellSelected:(id)sender {
NSLog(@"Cancel Selected");
}
(2) オブジェクトを生成する方法
一旦オブジェクトを生成して、改めてshowActionSheetPickerメソッドで表示するものです。 こちらでは、オブジェクト生成後、各種のパラメータをセットすることができます。
初期化メソッドで指定しきれないパラメータがある場合は、この方法を選択する必要があります。
コールバック先のメソッドは、先のものと同じです。
ActionSheetStringPicker *actionSheetPicker
= [[ActionSheetStringPicker alloc] initWithTitle:@"title"
rows:items
initialSelection:index
target:self
successAction:@selector(doneSelected:element:)
cancelAction:@selector(cancellSelected:)
origin:sender];
actionSheetPicker.hideCancel = YES; // 初期化メソッドで指定できなかったパラメータ
[actionSheetPicker showActionSheetPicker]; // 表示
(3) クロージャで指定する方法
先の2つは、コールバックメソッドを別に用意しましたが、これをクロージャで指定することもできます。 コールバック時の処理が簡潔な場合や、同じ処理を使い回す必要がない場合などは、この方が簡単かも知れません。
- (IBAction)tapButton:(id)sender {
NSArray *items = @[@"001", @"002", @"003", @"..."];
int index;
ActionSheetStringPicker *actionSheetPicker
= [[ActionSheetStringPicker alloc] initWithTitle:@"title"
rows:items
initialSelection:index
doneBlock: ^(ActionSheetStringPicker *picker, NSInteger selectedIndex, id selectedValue) {
NSLog([NSString stringWithFormat:@"%ld",selectedIndex]);
NSLog([NSString stringWithFormat:@"%@",selectedValue]);
} cancelBlock:^(ActionSheetStringPicker *picker) {
NSLog(@"Cancel Selected");
} origin:sender];
[actionSheetPicker showActionSheetPicker];
}
4 ピッカーの種類
各種のピッカーの使用方法を簡単に列挙します。 動作しているのは、GitHUbで公開されている、サンプルです。
(1) ActionSheetStringPicker
文字列配列で初期化する最も簡単なピッカーです。
NSArray *animals = @[@"Aardvark", @"Beaver", @"Cheetah", @"Deer", @"Elephant", @"Frog", @"Gopher", @"Horse", @"Impala", @"...", @"Zebra"];
[ActionSheetStringPicker showPickerWithTitle:@"Select Animal"
rows:self.animals
initialSelection:selectedIndex
target:self
successAction:@selector(animalWasSelected:element:)
cancelAction:@selector(actionPickerCancelled:)
origin:sender];
http://cocoadocs.org/docsets/ActionSheetPicker-3.0/2.0.5/Classes/ActionSheetStringPicker.html
(2) ActionSheetDatePicker
NSDataで初期化するピッカーです。 最大値や、最小値も設定できます。
ActionSheetDatePicker *actionPicker = [[ActionSheetDatePicker alloc] initWithTitle:@""
datePickerMode:UIDatePickerModeDate
selectedDate:self.selectedDate
target:self
action:@selector(dateWasSelected:element:)
origin:sender];
[actionPicker setMinimumDate:minDate]; // 最小値
[actionPicker setMaximumDate:maxDate]; // 最大値
UIDatePickerModeDateで、日付の表示形式を指定します。
typedef NS_ENUM(NSInteger, UIDatePickerMode) {
UIDatePickerModeTime, // 6 | 53 | PM
UIDatePickerModeDate, // November | 15 | 2007
UIDatePickerModeDateAndTime, // Wed Nov 15 | 6 | 53 | PM
UIDatePickerModeCountDownTimer, // 1 | 53
} __TVOS_PROHIBITED;
http://cocoadocs.org/docsets/ActionSheetPicker-3.0/2.0.5/Classes/ActionSheetDatePicker.html
(3) ActionSheetDistancePicker
距離を設定するインターフェースを提供します。
[ActionSheetDistancePicker showPickerWithTitle:@"Select Length"
bigUnitString:@"m"
bigUnitMax:330
selectedBigUnit:self.selectedBigUnit
smallUnitString:@"cm"
smallUnitMax:99
selectedSmallUnit:self.selectedSmallUnit
target:self
action:@selector(measurementWasSelectedWithBigUnit:smallUnit:element:)
origin:sender];
}
コールバックには、次のような値が返されます。
- (void)measurementWasSelectedWithBigUnit:(NSNumber *)bigUnit smallUnit:(NSNumber *)smallUnit element:(id)element {
self.selectedBigUnit = [bigUnit intValue];
self.selectedSmallUnit = [smallUnit intValue];
[element setText:[NSString stringWithFormat:@"%i m and %i cm", [bigUnit intValue], [smallUnit intValue]]];
}
http://cocoadocs.org/docsets/ActionSheetPicker-3.0/2.0.5/Classes/ActionSheetDistancePicker.html
(4) ActionSheetCustomPicker
こちらは、デリゲートクラスを作成して、きめ細かく内容を作成するものです。 UITableViewのデリゲートクラスのようなイメージです。
デリゲートクラスの設計については、下記をご参照ください。
ActionSheetPickerTableViewController.h
ActionSheetPickerTableViewController.m
ActionSheetPickerCustomPickerDelegate *delg = [[ActionSheetPickerCustomPickerDelegate alloc] init];
NSNumber *yass1 = @1;
NSNumber *yass2 = @2;
NSArray *initialSelections = @[yass1, yass2];
[ActionSheetCustomPicker showPickerWithTitle:@"Select Key & Scale"
delegate:delg
showCancelButton:NO
origin:sender
initialSelections:initialSelections];
http://cocoadocs.org/docsets/ActionSheetPicker-3.0/2.0.5/Classes/ActionSheetCustomPicker.html
5 最後に
今回は、ActionSheetにPickerが載っかった、ActionSheetPickerについて紹介させて頂きました。 UIActionSheetとUIAlertControllerに悩む必要もなくなります。
インラインでPickerを表示する場合や、Pickerを動かした時点でリアルで設定値が変わるようなインターフェースでなければ、このActionSheetPickerは非常にいいのでは?と感じました。