☆Cocoa Touch UIKit勉強(3)
画像取得・選択;UIImagePickerController
UIImagePickerControllerは、カメラでの撮影、および撮影後画像の選択(取得)を制御するためのビューである。
iPod touch(iPhone)のカメラアプリケーションとiPadを含む写真アプリケーションは主にこれから出来ている。
静止画(still image)及び動画(movie)が対象になる。
なぜかUINavigationControllerの子クラスになっている(デリゲートの関係か)。
カメラまわりはiOS4.0、というか第4世代iPhone/iPod touchで大幅に機能アップされたので、
それ以降しか対応していない項目も多い。
当然のことながら、カメラを持っていないiPad1では無効な部分も多い。
iPadではUIPopoverControllerの中からしか呼び出せない。
iOS4.3ではオーバーレイに関する仕様が変わった模様。iOS4.2.1までで正常に表示されていても、4.3では正常表示されない可能性があるので
確認が必要である。私が確認したのは以下の点。
- オーバーレイに小さなサイズのUIViewを与えると、指定位置に表示されず、全画面表示になってしまう
=オーバーレイは全画面表示のみになった様子
- オーバーレイにフルカラーpng画像付きボタンを配置した場合、画像内の透過が効かない。
本来透過されるべき部分が黒で表示されるので、ボタンがきれいに表示されない。
→256色にすればOK(iOS4.2.1まではフルカラーでもOKだった)
また、前面カメラで撮影すると、撮影後の画像の左右が逆になる。
カメラアプリケーションだけでなく、UIImagePickerControllerレベルでそうなってる。
iOS4.3にしてから気がついたので、iOS4.2.1ではどうだったか不明。
仕様かもしれないが、バグに近いと思う。
UIImagePickerController
| メソッド名 | 動作 |
| +(NSArray*)availableCaptureModesForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice
| カメラデバイスでサポートされるキャプチャーモードを返す
|
| +(NSArray*)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType
| 画像取得源として利用可能なメディアタイプを返す
|
| +(BOOL)isCameraDeviceAvailable:(UIImagePickerControllerCameraDevice)cameraDevice
| 指定のカメラが使えるかどうかを返す
|
| +(BOOL)isFlashAvailableForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice
| 指定カメラにフラッシュ機能があるかどうかを返す
|
| +(BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType
| デバイスが指定された画像取得源を用いた選択メディアをサポートするかどうかを返す
|
| -(void)takePicture | 指定されたカメラで静止画を撮影する |
| -(BOOL)startVideoCapture | 指定されたカメラで動画撮影を開始する |
| -(void)stopVideoCapture | 動画撮影を終了する |
| プロパティ名 | 属性 | 内容 |
| id <UINavigationControllerDelegate,UIImagePickerControllerDelegate> delegate | S | デリゲートを設定する |
| UIImagePickerControllerCameraCaptureMode cameraCaptureMode | RW
| 画像撮影モードを設定する
UIImagePickerControllerCameraCaptureMode(enum値)
| UIImagePickerControllerCameraCaptureModePhoto | 静止画 |
| UIImagePickerControllerCameraCaptureModeVideo | 動画 |
|
| UIImagePickerControllerCameraDevice cameraDevice | RW
| 画像撮影デバイスを指定する
UIImagePickerControllerCameraDevice(enum値)
| UIImagePickerControllerCameraDeviceRear | 背面カメラ(デフォルト) |
| UIImagePickerControllerCameraDeviceFront | 前カメラ |
|
| UIImagePickerControllerCameraFlashMode cameraFlashMode | RW
| 撮影時のフラッシュ状態を指定する
UIImagePickerControllerCameraFlashMode(enum値)
| UIImagePickerControllerCameraFlashModeOff | 点灯しない |
| UIImagePickerControllerCameraFlashModeAuto | 自動 |
| UIImagePickerControllerCameraFlashModeOn | 点灯する |
|
| UIView *cameraOverlayView | T | デフォルトの画像ピッカーの上に表示するカスタムビューを指定する
ところが、オーバーレイにはいろいろ制約があるので、自前でUIViewを重ねた方が良いと思う。
回転処理とかは自分でやらないといけないけど。
|
| NSArray *mediaTypes | C | メディアタイプの設定
利用可能なメディアタイプはavailableMediaTypesForSourceType:で得られる
メディアタイプ(UTI Image Content Types)
(
CFStringRef
構造体値)
| kUTTypeImage | 画像データ(抽象識別子);デフォルト |
| kUTTypeJPEG | JPEG |
| kUTTypeJPEG2000 | JPEF2000 |
| kUTTypeTIFF | TIFF |
| kUTTypePICT | QuickDraw PICT |
| kUTTypeGIF | GIF |
| kUTTypePNG | PNG |
| kUTTypeQuickTimeImage | QuickTime('qtif') |
| kUTTypeAppleICNS | Apple icon |
| kUTTypeBMP | Windows bitmap |
| kUTTypeICO | Windows icon |
|
| BOOL showsCameraControls | | YES=デフォルトのカメラコントロールがpicker内に見える
NO=cameraOverlayViewプロパティで指定するカスタムオーバーレイビューを表示する
|
| UIImagePickerControllerSourceType sourceType | RW
| 画像取得源
UIImagePickerControllerSourceType(enum値)
| UIImagePickerControllerSourceTypePhotoLibrary | 写真ライブラリ |
| UIImagePickerControllerSourceTypeCamera | 内蔵カメラ |
| UIImagePickerControllerSourceTypeSavedPhotosAlbum | 保存された写真 |
|
| NSTimeInterval videoMaximumDuration | | 動画の最大撮影時間を設定する
内蔵メモリには限りがあるので、無限撮影はできないようになっている。
時間以内でも空き容量がなくなったらたぶん止まる。
|
| UIImagePickerControllerQualityType videoQuality | RW
| 画質
UIImagePickerControllerQualityType(enum値)
| UIImagePickerControllerQualityTypeHigh | カメラでサポートしている最高画質 |
| UIImagePickerControllerQualityType640x480 | 640*480 |
| UIImagePickerControllerQualityTypeMedium | 中画質(デフォルト) WiFiで転送するにちょうど良いサイズ |
| UIImagePickerControllerQualityTypeLow | 低画質 |
|
デリゲートは2つのプロトコルを指定する。
UINavigationControllerDelegateについては
ナビゲーションコントローラー;UINavigationControllerの項参照のこと。
UIImagePickerControllerDelegate
| メソッド名 | 動作 |
| -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
| 静止画を撮影、または静止画または動画を選択したとき呼び出される。
infoには以下の値が入る。
- 静止画選択時:オリジナル画像と編集された画像を含んでいる辞書
- 動画選択時 :ファイルシステムURL
編集されているときには編集情報も含む。
| info辞書のキー値(NSString const*値) | 意味 | 辞書内容 |
| UIImagePickerControllerMediaType | ユーザーが選択したメディアタイプ | kUTTypeImage/kUTTypeMovie |
| UIImagePickerControllerOriginalImage | 撮影画像 | UIImage |
| UIImagePickerControllerEditedImage | 編集された画像 | UIImage |
| UIImagePickerControllerCropRect | オリジナル画像内編集領域長方形 | CGRectの不透明なタイプを含んでいるNSValueオブジェクト |
| UIImagePickerControllerMediaURL | ファイルシステムURL | NSURL |
|
| -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
| 選択処理が中断されたとき呼び出される。
|
こんな風にして撮影した画像を取り出す。
この例では、撮影が終わったら、即カメラ画面を消すようにしている。
-(void)imagePickerController:(UIImagePickerController *)picker_ didFinishPickingMediaWithInfo:(NSDictionary *)info
// 撮像終了処理(delegate)
// iOSが写真をしたら並行動作で呼び出され、この中を走っている間、メインも走り続ける
// キャンセル時はここには来ない
{
NSLog(@"imagePickerController");
// まずカメラ画面を消す
if (isiOS5over()) { // この判定関数は自分で作ること
[imgPicker dismissViewControllerAnimated:YES completion:NULL];
} else {
/// iOS4.xのみ
[imgPicker dismissModalViewControllerAnimated:YES];
}
// imageはこれを含むクラスのメンバー
image=[info objectForKey:UIImagePickerControllerOriginalImage]; // 撮影した画像を取得
//
NSLog(@"imagePickerController開放");
[imgPicker release];
}
UISearchBar
検索バーは検索入力用のテキストボックスを表示&入力するビューである。
あくまで表示と入力のみなので、検索処理そのものは自分で実装する必要がある。
UISearchBar
| プロパティ名 | 属性 | 内容 |
| id <UISearchBarDelegate> delegate | S | デリゲートを設定する |
| NSString *placeholder | C | テキストフィールド内にテキストがないときに表示される文字列 |
| NSString *text | C | 検索文字列(初期および現在) |
| NSArray *scopeButtonTitles | C | 範囲ボタンのタイトル文字列配列 |
| BOOL showsBookmarkButton | | ブックマークボタンを表示するかどうか |
| BOOL showsCancelButton | | キャンセルボタンを表示するかどうか |
| BOOL showsScopeBar | | スコープバーを表示するかどうか |
| BOOL showsSearchResultsButton | | 検索結果ボタンを表示するかどうか |
| BOOL searchResultsButtonSelected | G=isSearchResultsButtonSelected | 検索結果ボタンが選ばれているかどうか |
| NSInteger selectedScopeButtonIndex | | 選択されているスコープボタンの番号 |
UISearchBar *sb = [[[UISearchBar alloc] init] autorelease];
sb.delegate = self;
sb.prompt = @"タイトル";
sb.placeholder = @"検索ワードを入力してください";
sb.keyboardType = UIKeyboardTypeDefault;
sb.barStyle = UIBarStyleBlack;
sb.showsCancelButton = YES;
[self.view addSubview:sb];
//テーブルのヘッダーに配置する場合
tableView.tableHeaderView = sb;
UITabBar/UITabBarItem
UITabBarは「2つ以上のボタンから1つを選ぶためのコントロールクラスである。
1つ1つのボタンのことは「アイテム」と呼ぶ。これは、アイテムをタップすることで選択を変えるために使われることが多い。
UITabBarでは、アイテム選択時に強調表示(もしくは無変化)ではなく、アニメーションによる外観変更が出来る。
UITabBar
| メソッド名 | 動作 |
| -(void)setItems:(NSArray *)items animated:(BOOL)animated | タブバー上にアイテムを設定する(アニメーション付き) |
| -(void)beginCustomizingItems:(NSArray *)items | タブバー上のモーダルビューのカスタマイズを開始する |
| -(BOOL)endCustomizingAnimated:(BOOL)animated | モーダルビューを破棄するときにアニメーションを使うかどうか |
| -(BOOL)isCustomizing | タブバーがカスタマイズされているかどうか |
| プロパティ名 | 属性 | 内容 |
| id <UITabBarDelegate> delegate | S | デリゲートを設定する |
| NSArray *items | C | タブバー上に表示するアイテム |
| UITabBarItem *selectedItem | T | 選択中のアイテム |
デリゲートはUITabBarDelegateプロトコルで実装する。
UITabBarDelegate
| メソッド名 | 動作 |
-(void)tabBar:(UITabBar *)tabBar
| didSelectItem:(UITabBarItem *)item |
| didBeginCustomizingItems:(NSArray *)items |
| willBeginCustomizingItems:(NSArray *)items |
| didEndCustomizingItems:(NSArray *)items changed:(BOOL)changed |
| willEndCustomizingItems:(NSArray *)items changed:(BOOL)change |
|
| タブバーのアイテムが選択されるときに呼び出される(必須) |
| カスタマイズされたモーダルビューが表示された後に呼び出される |
| カスタマイズされたモーダルビューが表示される前に呼び出される |
| カスタマイズされたモーダルビューが破棄された後に呼び出される |
| カスタマイズされたモーダルビューが破棄される前に呼び出される |
|
UITabBarItemはタブバーのアイテムを実装するクラスである。
| メソッド名 | 動作 |
| -(id)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag |
システムで用意されているアイコンでタブバーにアイテムを追加する
UITabBarSystemItem(enum値)
| UITabBarSystemItemMore | |
| UITabBarSystemItemFavorites | |
| UITabBarSystemItemFeatured | |
| UITabBarSystemItemTopRated | |
| UITabBarSystemItemRecents | |
| UITabBarSystemItemContacts | |
| UITabBarSystemItemHistory | |
| UITabBarSystemItemBookmarks | |
| UITabBarSystemItemSearch | |
| UITabBarSystemItemDownloads | |
| UITabBarSystemItemMostRecent | |
| UITabBarSystemItemMostViewed | |
|
| -(id)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag | ユーザー作成のアイテムを追加する |
| プロパティ名 | 属性 | 内容 |
| (NSString *)badgeValue | C | 項目の右上角で周囲の赤い○の中に表示されるテキスト |
UITabBarController
UITabBarControllerは、複数の選択項目から、同時には1つしか選択できない画面遷移を管理するコントロールである。
画面遷移という意味で、UINavigationControllerに近い。
サブビューコントローラー群(それぞれをアイテムと呼ぶ)
[UITabBarController]----+---UIViewController 0;要素番号(index)
+---UIViewController 1
+---UIViewController 2
+---UIViewController 3
UITabBarController
| メソッド名 | 動作 |
| -(void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated | タブバーコントローラーにルートビューコントローラーを設定する |
| プロパティ名 | 属性 | 内容 |
| id <UITabBarControllerDelegate> delegate | S | デリゲートを設定する |
| NSArray *customizableViewControllers | C | このタブバーコントローラーで管理されるサブビューコントローラー群をカスタマイズする |
| UINavigationController *moreNavigationController | R | More NavigationControllerを管理するビューコントローラー |
| NSUInteger selectedIndex | | 選択中のタブアイテムの要素番号 |
| UIViewController *selectedViewController | S | 選択中のビューコントローラー |
| UITabBar *tabBar | R | コントローラーに割り付けられているタブバー |
| NSArray *viewControllers | C | タブバーで表示されているルートビューコントローラーの配列 |
// 画面(view1, view2, view3)をタブバーに追加する
NSArray *views = [NSArray arrayWithObjects:view1, view2, view3 nil];
[tbc setViewControllers:views animated:NO];
UIToolBar
ツールバーは1つまたは複数のボタン(アイテム)から1つを選択するコントロールクラスである。
通常全ての設定をIBで行ってしまうので、プログラム的にいじるのは有効無効を設定するくらいだろうが、
それは
UIControlの仕事である。
UIToolBar
| メソッド名 | 動作 |
| -(void)setItems:(NSArray *)items animated:(BOOL)animated | ツールバー上にアイテムを設定する(アニメーション付き) |
| プロパティ名 | 属性 | 内容 |
| UIBarStyle barStyle | | ツールバーの外観を指定する |
| UIColor *tintColor | T | ツールバーの色を指定する |
| BOOL translucent | SG=isTranslucent | ツールバーを半透明にするかどうか |
| NSArray *items | C | ツールバーに表示する項目 |
UIAlertView
アラートビューとは「警告画面」のことで、Windowsで言う所のダイアログに近い。
が、画面上はそこで止まってボタンを押すまで先に進まないが、
内部処理はアラートビューを表示するとすぐ次へ進んでしまうので注意が必要である。
アラートビューはIBでは設定出来ないのでプログラムからの指定が必須となる。
UIAlertView
| メソッド名 | 動作 |
-(id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ... | ボタンとデリゲートを持って初期化する。終端はnil |
| -(void)show | アニメーションを使ってレシーバーを表示する |
| -(NSInteger)addButtonWithTitle:(NSString *)title | titleのボタンを追加する |
| -(NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex | ボタン番号のtitleを返す |
| -(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated | ボタン番号のボタンを解放する(アニメーション付き) |
| プロパティ名 | 属性 | 内容 |
| id <UIAlertViewDelegate> delegate | S | デリゲートを設定する(nil=なし) |
| NSString *title | C | タイトル文字列 |
| NSInteger cancelButtonIndex | | キャンセルボタンのボタン番号(0~) |
| NSInteger firstOtherButtonIndex | R | 第1ボタンのボタン番号 |
| NSString *message | C | タイトルより詳細な説明文を記述する |
| NSInteger numberOfButtons | R | ボタンの数を返す |
| BOOL visible | RG=isVisible | 表示するかどうか |
デリゲートは
UIAlertViewDelegate
プロトコルに準拠する。
| メソッド名 | 動作 |
| -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
| ボタンが押されたときに呼び出される
initWithTitle:で設定している場合、cancelButtonTitle:が0、以下otherButtonTitlesが1~になる。
|
| -(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex |
アラートビューが表示される前に呼び出される |
| -(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex |
アラートビューが画面から消えた後に呼び出される |
| -(void)alertViewCancel:(UIAlertView *)alertView | アラートビューがキャンセルされる前に呼び出される |
| -(void)didPresentAlertView:(UIAlertView *)alertView | アラートビューがユーザーに示された後に呼び出される |
| -(void)willPresentAlertView:(UIAlertView *)alertView | アラートビューがユーザーに示され前に呼び出される |
アラートビュー表示中に電源を切ると異常動作するらしい。ただし、古い情報なので、最新のiOSではどうか不明。
- アラートを表示する
- 電源ボタンを押してスリープモードにする
- この時 didDismissWithButtonIndex が呼び出される;本来これはアラートビューが消えた後に呼び出されるべき
- スリープモードを解除
- アラートは閉じられていない
- アラートが開いている限り、電源ボタンを押すと何回でもdidDismissWithButtonIndexが呼び出される
これを避けるには、グローバルなフラグを持って制御するしかなさそう。
int pushFlag;
- 何か初期化処理のメソッド
{
pushFlag = false;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
// ボタンを押された時
{
pushFlag = true;
NSLog(@"clickedButtonAtIndex");
NSLog(@"buttonIndex:%d", buttonIndex);
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
// アラートビューが画面から消えた後に呼び出される
{
if (pushFlag) { // ボタンを押されてアラートビューを閉じるときのみ正規の処理とみなす
NSLog(@"didDismissWithButtonIndex");
NSLog(@"buttonIndex:%d", buttonIndex);
pushFlag = false;
}
}
UIActionSheet
アクションシートはダイアログの一種で、iPhone/iPodでは画面の下から「にゅっ」っと、
iPadでは画面の真ん中に出てきて、ボタンの選択を求める。
アクションシート外の画面をタッチすると自動的に閉じられる。そこがUIAlearViewとの最大の違いである。
アクションシートもIBでは設定出来ないのでプログラムからの指定が必須となる。
UIActionSheet
| メソッド名 | 動作 |
| -(id)initWithTitle:(NSString *)title delegate:(id <UIActionSheetDelegate >)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
destructiveButtonTitle:(NSString *)destructiveButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ...
|
アクションシートのインスタンスを作成する
|
| -(NSInteger)addButtonWithTitle:(NSString *)title | 指定したタイトルでボタンを追加する |
| -(NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex | 指定したインデックスのボタンのタイトルを返す |
| -(void)showInView:(UIView *)view | 指定したビューからレシーバを表示する |
| -(void)showFromTabBar:(UITabBar *)view | 指定したタブバーからレシーバを表示する |
| -(void)showFromToolbar:(UIToolbar *)view | 指定したツールバーからレシーバを表示する |
| -(void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated
| 指定されたバーボタン項目から始まるアクションシートを表示する
|
| -(void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated
| 指定されたビューから始まるアクションシートを示す
|
| -(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
| ボタンを押したことにしてアクションシートを消す |
| プロパティ名 | 属性 | 内容 |
| id <UIActionSheetDelegate> delegate | | デリゲートを設定する |
| NSString *title | C | タイトル文字列を設定する |
| NSInteger numberOfButtons | R | アクションシート上のボタン数を返す |
| NSInteger cancelButtonIndex | | キャンセルボタンの番号を返す |
| NSInteger destructiveButtonIndex | | 否定的なボタンの番号を指定する |
| NSInteger firstOtherButtonIndex | R | 一番目のボタンの番号を返す |
| UIActionSheetStyle actionSheetStyle | | スタイルを指定する
UIActionSheetStyle(enum値)
| UIActionSheetStyleAutomatic | ボタンバー(があればその)外観になる。なければデフォルトと同じ |
| UIActionSheetStyleDefault | デフォルト |
| UIActionSheetStyleBlackTranslucent | 黒い半透明のスタイル |
| UIActionSheetStyleBlackOpaque | 黒い不透明なスタイル |
|
| BOOL visible | RG=isVisible | 表示されているかどうか |
|
注:
アプリケーションがバックグラウンドに移行するとき、アクションシートは自動的に閉じられないらしい。
|
デリゲートは
UIActionSheetDelegateプロトコルに準拠する。
直接プログラムで記述方法を書く。
// ヘッダー側
@interface CamViewController : UIViewController <UIActionSheetDelegate>
{
}
// アクションシートのインスタンス
- (IBAction)showCamSheet;
@end
// 本体側
- (IBAction)showCameraSheet
{
// アクションシートを作る
UIActionSheet* sheet;
sheet = [[UIActionSheet alloc]
initWithTitle:@"Select Soruce Type" // タイトル文字列
delegate:self // デリゲート処理の存在メソッド(ここでは自身の中)
cancelButtonTitle:@"Cancel" // キャンセルボタンの文字列
destructiveButtonTitle:nil // 否定的ボタンの文字列
otherButtonTitles:@"Photo Library", @"Camera", @"Saved Photos", nil // 他のボタンの文字列(可変引数なので必要なだけ)
];
[sheet autorelease];
// アクションシートを表示する
[sheet showInView:self.view];
}
showCamSheetでは、アクションシートの表示を行っている。
まず、UIActionSheetクラスのインスタンスを作る。
ボタンは可変引数で複数指定できる。
actionSheet:clickedButtonAtIndex:メソッドはボタンをクリックしたときに呼び出される。
- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
// 閉じるときの処理(デリゲート)
{
// ボタンインデックスをチェックする
// buttonIndexは押されたボタンの番号;0~cancelButtonTitle、destructiveButtonTitle、otherButtonTitlesの数-1
switch (buttonIndex) {
default:
break;
case 0:
~
break;
case 1:
~
break;
case 2:
~
break;
}
~
}