外ぶらっとしに行って、ついでにiPadを買いそうになりましたw Wifiモデルでも並ばなきゃ買えなかったので、諦めましたが。
さて、UIPickerViewの続き。 今度は2つのコンポーネントを表示。
まずコンスタンスとして2つのコンポーネントの番号を設定しておく
#define kPlayerComponent 0
#define kPostionComponent 1
次に、データ配列を作成
- (void)viewDidLoad {
NSArray *playerArray = [[NSArray alloc] initWithObjects:
@"荒木", @"大島", @"森野", @"ブランコ",
@"和田", @"井端", @"セサル", @"谷繁",nil];
self.players = playerArray;
[playerArray release];
NSArray *positionArray = [[NSArray alloc] initWithObjects:
@"ピッチャー", @"キャッチャー", @"ファースト", @"セカンド",
@"サード", @"ショート", @"レフト", @"センター", @"ライト",nil];
self.positions = positionArray;
[positionArray release];
}
ここまではほぼ前と同じ。 UIPickerViewのデータは、この書籍では条件分岐で返してます。
#pragma mark Picker Data source method
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
if (component == kPlayerComponent) {
return [self.players count];
} else if (component == kPostionComponent) {
return [self.positions count];
}
return 0;
}
#pragma mark Picker Delegate method
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component {
if (component == kPlayerComponent) {
return [self.players objectAtIndex:row];
} else if (component == kPostionComponent) {
return [self.positions objectAtIndex:row];
}
return 0;
}
うーん、汎用的にするには連想配列にすべきですね。 次は、NSDictionaryを利用した場合。
その前に参考書籍には、アメリカのZIPコードデータ「statedictionary.plist」が必要。 海外サイトにサンプルソースがあるらしいので検索。
ここのフォーラムにあるのだが、Regist & Loginしないとダウンロードできないです(^^;) さらにソースの場所もわかりにくいのでメモ・・・以下のフォーラムにあります。
Beginning iPhone Development ‹ Hey! Over here! Here's the source code to the book!!!
ダウンロードしたら「Resources」に「statedictionary.plist」を入れておく。 今回のサンプルは、基本は変わらないが、statedictionary.plistを読み込んでNSDictionaryとして扱うのがポイント。
- (void)viewDidLoad {
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle
pathForResource:@"statedictionary"
ofType:@"plist"
];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.stateZips = dictionary;
[dictionary release];
NSArray *components = [self.stateZips allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)];
self.states = sorted;
NSString *selectedState = [self.states objectAtIndex:0];
NSArray *array = [self.stateZips objectForKey:selectedState];
self.zips = array;
[super viewDidLoad];
}
外部ファイルの読み込みは、Bundleを用意して
NSBundle *bundle = [NSBundle mainBundle];
Resourcesからのファイルパスを生成して、
NSString *plistPath = [bundle pathForResource:@"statedictionary" ofType:@"plist"];
NSDictionaryに格納する。
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
NSArray、NSDictionaryの特記として
・allKeys ・objectForKey ・sortedArrayUsingSelector
@selector(compare:)の「compare」はNSComparisonResultのメソッド。 大文字小文字を区別しない「caseInsensitiveCompare」もある。
次に、ピッカーが選択された時の動作
-(void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {
if (component == kStateComponent) {
NSString *selectedState = [self.states objectAtIndex:row];
NSArray *array = [stateZips objectForKey:selectedState];
self.zips = array;
[picker selectRow:0 inComponent:kZipComponent animated:YES];
[picker reloadComponent:kZipComponent];
}
}
didSelectRow inComponentメソッドを記述してやるだけでOK。 条件がZipコンポーネントでなく、Stateコンポーネントなのが、思考的にややこしい。 引数のcomponentは動かしたコンポーネント番号ではなく、
全コンポーネントをチェック時のコンポーネント番号
らしい。 つまりstateデータを更新したければ、stateのコンポーネント番号でOK Eventのプログラム思考でいくと、何か変な感じですがw