メモ帳の作成(4)~ピッカービュー

2010. 07. 13
テキストビューのフォントの種類とサイズを選択するのが、下部ツールバー左にある『Font』ボタンを押すと出てくるピッカービューです。

510


●UIPickerViewクラス

UIPickerViewクラスは、ピッカービューと呼ばれる糸車やスロットマシーンのような一つ以上の値を設定できるオブジェクトを実装します。

ユーザは、回転するホイールに行で並べられている値から、セレクションインジケータの示す値を選択します。

UIDatePickerクラスは、UIPickerViewのカスタムサブクラスとして、日付と時間の表示に使用することができます。

※注:実際のUIKitフレームワークの継承関係としては、UIPickerViewとUIDatePickerは直接継承されていません。
(UIDatePickerはUIControlのサブクラスになっています)

NSObject
    |
    ∟UIResponder
            |
            ∟UIView
                    |
                    ∟UIPickerView
                    |
                    ∟UIControl
                            |
                            ∟UIDatePicker

UIKit Framework Reference/Introduction/Figure I-1  UIKit class hierarchy』参照

例として、『時計』アプリケーションの『アラーム』で追加ボタン(『+』)をタップして参照してください。

ピッカービューは、コンポーネントと行から成るユーザインターフェイスを提供します。

コンポーネントはホイールのことで、ホイールは一組のインデックスの付けられたアイテム(行)を持っています。

各コンポーネントは、ピッカービューにおける位置(左から右への)のインデックスも持ちます。

コンポーネントの各行のコンテンツは、文字列またはラベル(UILabel)や画像(UIImageView)などのビューオブジェクトを持ちます。

UIPickerViewオブジェクトには、コンポーネントと行の番号を提供するため、コンポーネントとデータソースを構築するための協調するデリゲートが必要です。

デリゲートはUIPickerViewDelegateプロトコルを採用し、各コンポーネントの行の矩形を描画して返すメソッドを実装する必要があります。

また文字列またはビューといった各コンポーネントの行のコンテンツを提供し、それは通常新しいセレクションまたはデセレクションに応答します。

データソースはUIPickerViewDataSourceプロトコルを採用し、各コンポーネント数と行数を返すメソッドを実装する必要があります。

コンポーネントの行はreloadComponent:メソッド、また全てのコンポーネントの行はreloadAllComponentsメソッドを呼び出すことで動的に変更することができます。

これらのメソッドを呼び出す場合、ピッカービューは新しいコンポーネントと行データをデリゲートに要求し、データソースに新しいコンポーネントと行コンテンツを要求します。

ピッカービューは、あるコンポーネントで選択された値によって、他のコンポーネントの値が変更される場合に再読み込みします。

例えば、あるコンポーネントの行の値を2月から3月に変更した場合、月の日付を表すコンポーネントを再読み込みします。


●UIPickerViewDelegateプロトコル

UIPickerViewオブジェクトのデリゲートはUIPickerViewDelegateプロトコルを採用し、ピッカービューの構築に必要なデータを提供するいくつかのメソッドを実装する必要があります。

デリゲートは、各コンポーネントの高さ、幅、行タイトル、行のビューコンテンツといった、このプロトコルに必要なメソッドを実装します。

また、各コンポーネントの行の文字列またはビューのコンテンツを提供する必要があります。

通常はコンポーネントの行の新しいセレクションまたはデセレクションに応答する、他のオプションメソッドをデリゲートは実装します。

コンポーネントや行、行のコンテンツ、コンポーネントの行のセレクションまたはデセレクションについての詳細は『UIPickerView Class Reference』を参照してください。


●UIPickerViewDataSourceプロトコル

UIPickerViewDataSourceプロトコルは、UIPickerViewオブジェクトとアプリケーションのピッカービュー用のデータモデルの間を取りなすオブジェクトのために採用する必要があります。

データソースはピッカービューに、コンポーネントの数と各コンポーネントの行数、そしてピッカービューで表示するデータを提供します。

このプロトコルの両メソッドが必要です。


●データソースとデリゲートの設定

上記の説明にあるように、ピッカービューを利用するにはUIPickerViewDelegateプロトコルとUIPickerViewDataSourceプロトコルを採用する必要があります。

本書ではInterface Builder上で設定しており、DocumentウィンドウでPickerを選択し、Inspectorウィンドウに出てくるOutletsのdataSourceとdelegateをMemoインスタンスに接続しています。

505

この理屈でいえば『メモ帳の作成(2)~テキストビュー』でのUITextViewDelegateプロトコルもコードで記述するかInterface Builderで接続するかのどちらかで良いと思われます。

個人的にはヘッダファイルに記述した方が分かり易い気がしますが、この辺は各プログラマの見解やコーディングルールに依ると思います。

コードで書くと以下のようになります。
(太字が追加した部分)

#import <Foundation/Foundation.h>

@interface Memo : NSObject <UITextViewDelegate, UIPickerViewDelegate, UIPickerViewDataSource> {
// アウトレット
    IBOutlet UITextView *memoView; // メモ入力用のテキストビュー
    IBOutlet UIPickerView *fontPicker; // フォント選択用ピッカービュー
    IBOutlet UIImageView *imageView; // 背景画像用イメージビュー
    IBOutlet UIToolbar *topToolbar; // 画面上部のツールバー
    IBOutlet UIToolbar *btmToolbar; // 画面下部のツールバー

    // ピッカービューに表示するデータ
    NSMutableArray *fontNames; // フォント名一覧
    NSArray *fontSizes; // フォントサイズ一覧
}
// アクションメソッド
- (IBAction)selectFont; // フォント選択画面の表示/非表示
- (IBAction)doneMemoEdit; // メモ編集完了
- (IBAction)clearMemo; // メモクリア
- (IBAction)showAbout; // アバウト画面表示

@end

511


●Memoクラスの初期化処理

Memoクラスの初期化メソッドは2つあります。

initメソッドではピッカービューのフォントの種類とサイズのデータソースの配列を生成します。

フォントの種類は『メモ帳の作成(3)~フォント』で追加したsetupFontNamesメソッドで生成し、サイズはfontSizesとしてinitメソッド内で生成しています。

awakeFromNibはnibファイル読み込み完了後に、上部ツールバーとピッカービューを非表示にする処理を行っています。

// 初期化メソッド
- (id)init {
    self = [super init];
    if (self != nil) {
        // フォント一覧を取得
        [self setupFontNames];

        // フォントサイズ一覧を取得
        fontSizes = [[NSArray arrayWithObjects:@"9", @"10", @"12", @"14", @"18", @"24", @"36", @"72", nil] retain];
    }
    return(self);
}

// Nibファイルからの読み込み完了後の初期化メソッド
- (void)awakeFromNib {
    [super awakeFromNib];

    // 画面上部のツールバーとピッカービューを隠す
    topToolbar.alpha = 0.0f;
    fontPicker.alpha = 0.0f;
}

506

ツールバーやピッカービューなどのビューアイテムは、アルファ値を0にすると応答しなくなると本書の記述で知りました。


●表示関係のデータソースとデリゲートのメソッド実装

ピッカービューの外観を設定するメソッドが4つあり、内2つはUIPickerViewDataSourcesプロトコルの必須メソッドで、残り2つがUIPickerViewDelegateのメソッドになります。

numberOfComponentsInPickerView:はコンポーネント(ホイール)数を指定するメソッドで、ここではフォントの種類とサイズの2つになります。

pickerView:widthForComponent:は各コンポーネントの幅を指定するメソッドで、種類の幅は240ピクセル、サイズの幅は60ピクセルになります。

pickerView:numberOfRowsInComponent:は各コンポーネントの行数を取得するメソッドで、種類およびサイズの配列の要素数になります。

pickerView:titleForRow:forComponent:は各行の要素を取得するメソッドで、種類およびサイズの配列の要素になります。

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)view {
    return(2);    // コンポーネント数は2
}

-(CGFloat)pickerView:(UIPickerView *)view widthForComponent:(NSInteger)comp {
    if (comp == 0) return(240);    // フォント一覧の幅は240
    else return(60);    // フォントサイズの幅は60
}

- (NSInteger)pickerView:(UIPickerView *)view numberOfRowsInComponent:(NSInteger)comp {
    // 各配列の要素数を返す
    if (comp == 0) return([fontNames count]);
    else return([fontSizes count]);
}

- (NSString *)pickerView:(UIPickerView *)view titleForRow:(NSInteger)row
forComponent:(NSInteger)comp {
    // 各配列の指定インデックスのオブジェクトを返す
    if (comp == 0) return([fontNames objectAtIndex:row]);
    else return([fontSizes objectAtIndex:row]);
}

507


・numberOfComponentsInPickerView:
(UIPickerViewDataSourceプロトコル)

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

ピッカービューが呼び出す、必要なコンポーネント数です。(必須)

戻り値はピッカービューが表示するコンポーネント(またはカラム)数になります。

pickerView:データを要求するピッカービューを指定します。


・pickerView:widthForComponent:
(UIPickerViewDelegateプロトコル)

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component

ピッカービューが呼び出す、必要な行のコンテンツの表示に使う行幅です。

戻り値は、行の幅をポイントで示したfloat値になります。

pickerView:データを要求するピッカービューを指定します。

component:pickerViewのコンポーネントを識別する0から始まる番号を指定します。
コンポーネントは左から右に番号付けされます。


・pickerView:numberOfRowsInComponent:
(UIPickerViewDataSourceプロトコル)

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

ピッカービューが呼び出す、必要な指定したコンポーネントの行数です。(必須)

pickerView:データを要求するピッカービューを指定します。

component:pickerViewのコンポーネントを識別する0から始まる番号を指定します。
コンポーネントは左から右に番号付けされます。


・pickerView:titleForRow:forComponent:
(UIPickerViewDelegateプロトコル)

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

ピッカービューが呼び出す、必要なコンポーネントの行に与えるタイトルです。

pickerView:データを要求するピッカービューを指定します。

row:コンポーネントの行を識別する0から始まる番号を指定します。
行は上から下に番号付けされます。

component:pickerViewのコンポーネントを識別する0から始まる番号を指定します。
コンポーネントは左から右に番号付けされます。


●イベント関係のデリゲートのメソッド実装

ピッカービューのコンポーネントで行が選択された場合の処理を記述するのがpickerView:didSelectRow:inComponent:メソッドです。

ここではフォント名とサイズを取得して、テキストビューのフォントに適用します。

- (void)pickerView:(UIPickerView *)view didSelectRow:(NSInteger)row inComponent:(NSInteger)compo {
    // フォント一覧側の選択行の番号を取得
    NSUInteger selectedFont = [view selectedRowInComponent:0];

    // 選択されたフォント名を取得
    NSString *fontName = [fontNames objectAtIndex:selectedFont];

    // サイズ一覧側の選択行の番号を取得
    NSUInteger selectedSize = [view selectedRowInComponent:1];

    // 選択されたフォントサイズを取得
    NSString *strFontSize = [fontSizes objectAtIndex:selectedSize];
    CGFloat fontSize = [strFontSize floatValue];

    // テキストビューにフォントを設定
    memoView.font = [UIFont fontWithName:fontName size:fontSize];
}

508


・pickerView:didSelectRow:inComponent:
(UIPickerViewDelegateプロトコル)

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

コンポーネントの行をユーザが選択した場合に、ピッカービューによって呼び出されます。

ユーザの選択した値の決定に、デリゲートはrowインデックスを使って、コンポーネントの構築に使用した配列の位置にある値を求めます。

pickerView:データを要求するピッカービューを指定します。

row:コンポーネントの行を識別する0から始まる番号を指定します。
行は上から下に番号付けされます。

component:pickerViewのコンポーネントを識別する0から始まる番号を指定します。
コンポーネントは左から右に番号付けされます。


・selectedRowInComponent:
(UIPickerViewクラス)

- (NSInteger)selectedRowInComponent:(NSInteger)component

指定したコンポーネントで選択された行のインデックスを返します。

戻り値は選択された行の0から始まるインデックス番号、または行が選択されなかった場合は-1を返します。

component:pickerViewのコンポーネントを識別する0から始まる番号を指定します。


・fontWithName:size:
(UIFontクラス)

+ (UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize

指定したフォント名とサイズでフォントオブジェクトを生成して返します。

フォントファミリーから指定したフォント名を取得するには、fontNamesForFamilyName:メソッドを使うことができます。

fontName:完全なフォント名を指定します。
この名前はフォントファミリー名と指定したフォントのスタイル情報を含みます。

fontSize:フォントのスケールをポイントで指定します。
この値は0.0以上を指定する必要があります。


●ピッカービューの表示/非表示処理

『Font』ボタンが押された場合の処理で、ピッカービューの表示/非表示時のアニメーションの設定をしています。

- (IBAction)selectFont {
    // ピッカービューをフェードしながら表示/非表示を行う
    if (fontPicker.alpha == 0.0f) [fontPicker fadeTo:1.0f];
    else [fontPicker fadeTo:0.0f];
}

509



参考文献

UIPickerView Class Reference

UIPickerViewDelegate Protocol Reference

UIPickerViewDataSource Protocol Reference

UIFont Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る






bose_soundsport_free
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
09 | 2017/10 | 11
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

bose_soundsport_free
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR