☆Cocoa Touch UIKit勉強(2)
UIControl
UIControlは、
+---UIButton
+---UISwitch
+---UISegmentedControl
+---UISlider
+---UIDatePicker
+---UITextField
+---UIPageControl
のビューを配下に持つコントロールクラスである。基本的には、それらに共通する表示属性や
タッチイベントの処理を持っている(表示位置は、さらに親となるUIView.frameが持っている)。
UIControlを意識的に操作することはほとんどない。少なくとも私は一度もない。
が、UIBotton等のクラスの操作をしていると思ったら、実はその親のUIControlをいじっている、という次第である。
UIControl
| プロパティ名 | 属性 | 内容 |
| BOOL enabled | G=isEnabled | レシーバーが有効かどうか設定する
一時的に使えなくする時はこれをNOに設定する。
|
| BOOL highlighted | G=isHighlighted | レシーバーが強調表示されているか |
| BOOL selected | G=isSelected | レシーバーが選択状態にあるかどうか |
| BOOL touchInside | RG=isTouchInside | タッチが境界の内部かどうか |
| BOOL tracking | RG=isTracking | レシーバーがイベントに関係する現在の追跡しているタッチイベントを示しているかどうか |
| UIControlState state | R | レシーバーの状態
UIControlState(enum値)
| UIControlStateNormal | 通常状態 |
| UIControlStateHighlighted | 強調表示 |
| UIControlStateDisabled | 無効 |
| UIControlStateSelected | 選択中 |
|
| メソッド名 | 動作 |
| -(NSArray *)actionsForTarget:(id)target forControlEvent:(UIControlEvents)controlEvent |
ターゲットと特定のコントロールイベントに関連するactionメソッドを設定する
=特定のイベントに対する呼び出しインスタンスメソッドを設定する
UIControlEvents(enum値)
| UIControlEventTouchDown | タッチ-ダウン |
| UIControlEventTouchDownRepeat | タッチ-ダウン繰り返し(UITouch tapCountメソッド) |
| UIControlEventTouchDragInside | コントロール内部での指のドラッグ |
| UIControlEventTouchDragOutside | コントロール外部だけの指のドラッグ |
| UIControlEventTouchDragEnter | コントロール内部への指のドラッグ |
| UIControlEventTouchDragExit | コントロール境界内→外への指のドラッグ |
| UIControlEventTouchUpInside | コントロール境界内部でのタッチ-アップ |
| UIControlEventTouchUpOutside | コントロール境界外部でのタッチ-アップ |
| UIControlEventTouchCancel | コントロールへの現在のタッチをキャンセルするシステムイベント |
| UIControlEventValueChanged | ドラッグまたは別の操作で、一連の異なる値を返す |
| UIControlEventEditingDidBegin | UITextFieldオブジェクトで、境界内に入ることにより編集を開始する |
| UIControlEventEditingChanged | UITextFieldオブジェクトで、編集による更新を起こすタッチ |
| UIControlEventEditingDidEnd | UITextFieldオブジェクトで、境界外に出ることで編集を終了する |
| UIControlEventEditingDidEndOnExit | UITextFieldオブジェクトで、編集を終えるタッチ |
| UIControlEventAllTouchEvents | 全タッチイベント |
| UIControlEventAllEditingEvents | UITextFieldオブジェクトへの全ての編集イベント |
| UIControlEventApplicationReserved | アプリケーション用予約領域 |
|
| -(void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents |
特定イベントに、ターゲットとアクションを追加する
|
| -(void)removeTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents |
特定イベントのターゲットとアクションを削除する
|
| -(UIControlEvents)allControlEvents | レシーバーに割り付けられている全てのコントロールイベントを返す |
| -(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
| 発生したイベントに関連するタッチがコントロールの境界に入るとき、コントロールに送る
|
| -(void)cancelTrackingWithEvent:(UIEvent *)event
| 発生したイベントに関連する追跡(トラッキング)をキャンセルするようコントロールに通知する
|
| -(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
| コントロール境界の中で行われたイベントに関連したタッチを追跡して連続的にコントロールに送る
|
| -(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
| 行われたイベントのための最後のタッチが完全に終わるとき コントロールに追跡を終えるよう通知する
|
| -(void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event | ターゲットにイベントに対応するアクションを発生させる |
| -(void)sendActionsForControlEvents:(UIControlEvents)controlEvents | 与えられたコントロールイベントのアクションのメッセージを送る |
UILabel
ラベルは文字列を表示するビューである。表示するだけなので、他には何もしない。
基本は1行だけど、複数行表示も出来るらしい。
UILabel
| プロパティ名 | 属性 | 内容 |
| NSString *text | C | 表示文字列 |
| UIFont *font | T | フォントの設定 |
| BOOL enabled | G=isEnabled | テキスト表示のON/OFF |
| BOOL highlighted | G=isHighlighted | 強調表示表示するかどうか |
UIButton
単独のボタン。
UIButton
| プロパティ名 | 属性 | 内容 |
| NSString* currentTitle | RT | ボタンに表示されている現在のタイトル |
| UIColor *currentTitleColor | RT | タイトルの表示色 |
| UIColor *currentTitleShadowColor | RT | タイトルの影の色 |
| UIImage *currentImage | RT | ボタン画像 |
| UIImage *currentBackgroundImage | RT | ボタン背景画像 |
| メソッド名 | 動作 |
| -(void)setTitle:(NSString *)title forState:(UIControlState)state | 状態別タイトルを設定する。
ボタンの文字列はプロパティでは変更出来ないので、必ずこのメソッドを使う。
ローカライズするときに必須である。
UIControlState(enum値)
| UIControlStateNormal | 通常状態 |
| UIControlStateHighlighted | 強調表示された状態 |
| UIControlStateDisabled | 不可状態 |
| UIControlStateSelected | 選択中状態 |
| UIControlStateApplication | アプリケーションで追加される状態 |
|
| -(void)setTitleColor:(UIColor *)color forState:(UIControlState)state | 状態別タイトル色設定 |
| -(void)setTitleShadowColor:(UIColor *)color forState:(UIControlState)state | 状態別タイトル背景色設定 |
| -(UIColor *)titleShadowColorForState:(UIControlState)state | 状態別タイトル背景色取得 |
| -(NSString *)titleForState:(UIControlState)state | 状態別タイトル取得 |
| -(UIImage *)backgroundImageForState:(UIControlState)state | 状態別背景画像取得 |
| -(UIImage *)imageForState:(UIControlState)state | 状態別ボタン画像取得 |
| -(void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state | 状態別背景画像設定 |
| -(void)setImage:(UIImage *)image forState:(UIControlState)state | 状態別ボタン画像設定 |
UIBarButtonItem
UIBarButtonItemはナビゲーションバー上に配置するボタン。
UIBarButtonItem
| プロパティ名 | 属性 | 内容 |
| id target | S | ボタンをタップした時にメッセージを送るメソッドのオブジェクト |
| SEL action | | ボタンをタップした時にメッセージを送るメソッドのセレクタ |
| メソッド名 | 動作 |
| -(id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action
| 指定された画像と他のプロパティを使って初期化する
|
| -(id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action
| 指定されたタイトルと他のプロパティを使って初期化する
|
| -(id)initWithCustomView:(UIView *)customView
| カスタムビューを使っての初期化
|
ナビゲーションバーに配置するボタン UIBarButtonItem の見た目を完全に画像にするには以下のようにすると良いらしい。
UIButton *customView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 95, 33)];
[customView setBackgroundImage:[UIImage imageNamed:@"appstore.png"]
forState:UIControlStateNormal];
[customView addTarget:self
action:@selector(appstoreAction)
forControlEvents:UIControlEventTouchUpInside
];
UIBarButtonItem* buttonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
self.navigationItem.rightBarButtonItem = buttonItem;
initWithImage:ではボタン内は画像になるけど、枠が残ってしまうらしい。
UISwitch
スイッチはON/OFF二値を表すビューである。いや、これ以外に何を書けと(^_^;)。
UISwitch
| プロパティ名 | 属性 | 内容 |
| BOOL on | G=isOn | ON/OFFどちらか |
| メソッド名 | 動作 |
| -(id)initWithFrame:(CGRect)frame | 初期化 |
UISegmentedControl
セグメントコントロールは、複数の選択項目から排他的に1つを選ぶビューである。
UISegmentedControl
| プロパティ名 | 属性 | 内容 |
| BOOL momentary | G=isMomentary | YES=押下時、一瞬だけ選択状態になる/NO=常時選択状態になる |
| NSInteger selectedSegmentIndex | | 選択項目番号(最終的にタッチしていた項目;0~)
UISegmentedControlNoSegment:選択項目なし(デフォルト)
selectedSegmentIndex=-1で選択を禁止する
|
| メソッド名 | 動作 |
| -(id)initWithItems:(NSArray *)items | 項目名または画像をもって初期化する
itemsがNSStringの配列の時は文字列、UIImageのときは画像
|
| -(void)insertSegmentWithTitle:(NSString *)title atIndex:(NSUInteger)segment animated:(BOOL)animated | 文字列で項目を追加する |
| -(void)insertSegmentWithImage:(UIImage *)image atIndex:(NSUInteger)segment animated:(BOOL)animated | 画像で項目を追加する |
| -(void)removeAllSegments | 項目を全削除する |
| -(void)removeSegmentAtIndex:(NSUInteger)segment animated:(BOOL)animated | 指定項目を削除する(アニメーション付き) |
>
| -(void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSUInteger)segment | 指定項目を有効にする |
| -(void)setImage:(UIImage *)image forSegmentAtIndex:(NSUInteger)segment | 画像で項目を設定する |
| -(void)setTitle:(NSString *)title forSegmentAtIndex:(NSUInteger)segment | 文字列で項目を設定する |
| -(void)setWidth:(CGFloat)width forSegmentAtIndex:(NSUInteger)segment | 指定項目の幅を設定する |
UISlider
スライダーUISliderは、スライダーを動かして連続した値を得るビューである
UISlider
| プロパティ名 | 属性 | 内容 |
| float value | | 現在値 |
| float maximumValue | | 最大値 |
| float minimumValue | | 最小値(デフォルトは0.0) |
| BOOL continuous | G=isContinuous | 値が変更されるたびに連続的に更新イベントを呼び出すかどうか
YES=更新中随時呼び出し、NO=決定時呼び出しのみ
呼び出すメソッドは、親クラスであるUIControlのaddTarget:で指定する
|
| メソッド名 | 動作 |
| -(void)setValue:(float)value animated:(BOOL)animated | 値を設定する(アニメーション指定付き) |
| -(void)setMaximumTrackImage:(UIImage *)image forState:(UIControlState)state | 指定されたコントロール状態に最大値画像を設定する |
| -(void)setMinimumTrackImage:(UIImage *)image forState:(UIControlState)state | 指定されたコントロール状態に最小値画像を設定する |
| -(void)setThumbImage:(UIImage *)image forState:(UIControlState)state | 指定されたコントロール状態に指標画像を設定する |
スライダーの現在値を連続で取得するには以下のようになる。
// どこかの初期化
slider = [[UISlider alloc] initWithFrame:CGRectMake(~,~,~,~)];
[slider addTarget:self action:@selector(updateSlider:)
forControlEvents:UIControlEventValueChanged]; // これは親であるUIControlのメソッド
[self.view addSubview:slider];
slider.continuous=YES;
- (void) updateSlider:(UISlider *)aSlider
{
float number = aSlider.value;
~何かしらの処理~
}
@end
この場合、スライダーを動かすたびに(仮に高速で移動させても何回か)updateSliderが呼び出されるので、
「~何かしらの処理~」が重たかった場合には応答が遅くなる。
この場合、実読み出しタイミングを制御することで回避できる。
@interface newSlider : UISlider
{
UISlider *slider;
NSTimer *interval;
float lastValue;
}
@end
@implement newSlider
{
- (id)initWithFrame:(CGRect)rect
{
slider = [[UISlider alloc] initWithFrame:rect];
[slider addTarget:self action:@selector(updateSlider:)
forControlEvents:UIControlEventValueChanged]; // これは親であるUIControlのメソッド
[self.view addSubview:slider];
slider.continuous=YES;
slider.lastValue=slider.minimumValue-1.0; // 絶対に一致しない値を最初値にしておく
}
- (void) updateSlider:(UISlider *)aSlider
{
float number = aSlider.value;
if (lastValue != number) { // 値が変わったときのみ
lastValue = number; // 前回値を保存
// 移動した0.05秒後に実際の値を読むようにする
if (interval) { // 前のタイマー設定があるときは先にそれを止めてしまう
[interval invalidate]; // タイマーを停止する
[interval release]; // インスタンスの解放
}
// スライダーの値を読むのは0.05秒単位にしてしまう
interval = [
[NSTimer scheduledTimerWithTimeInterval:0.05
target:self
selector:@selector(updateSliderFromTimer)
userInfo:nil
repeats:NO] // 繰り返しなし
retain];
} // 値が変わらないときは何もしない
}
- (void) updateSliderFromTimer
{
~何かしらの処理~
}
- (void) dealloc
// 解放処理(オーバーライド)
{
[slider release];
[interval release];
[super dealloc];
}
@end
呼び出すインスタンスはnewSliderで作る。
UIPickerView
項目ピッカー;UIPickerViewは、くるくる回して項目を選択するビューである。選択中シンボルあり/なし設定出来る。

(選択中シンボルあり)

(選択中シンボルなし)
日時ピッカーのUIDatePickerとよく似ているが、UIDatePickerはUIPickerViewの子クラスではない。
UIPickerView
| プロパティ名 | 属性 | 内容 |
| id <UIPickerViewDataSource> dataSource | S | データ源を指定する |
| id <UIPickerViewDelegate> delegate | S | デリゲートを設定する |
| BOOL showsSelectionIndicator | | 選択中シンボルを表示するかどうか |
| NSInteger numberOfComponents | R | 桁数を返す |
| メソッド名 | 動作 |
| -(NSInteger)selectedRowInComponent:(NSInteger)component | 指定桁の選択中行番号(0~)を返す |
| -(NSInteger)numberOfRowsInComponent:(NSInteger)component | 指定桁の項目数指定 |
| -(void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated | 行を選択する(アニメーション付き)
PickerがIBActionでインスタンスと接続され、かつPickerが表示された状態でのみ有効。
|
| -(void)reloadAllComponents | 全桁全項目を読み直す |
| -(void)reloadComponent:(NSInteger)component | 指定桁を読み直す |
| -(CGSize)rowSizeForComponent:(NSInteger)component | 指定桁の幅を返す |
| -(UIView *)viewForRow:(NSInteger)row forComponent:(NSInteger)component | 指定項目の行のビューを返す |
項目数はUIPickerViewDataSourceプロトコルで別途実装する。当然必須である。
UIPickerViewDataSource
| メソッド名 | 動作 |
| -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView | 列数を返す |
| -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component | 指定行の項目数を返す |
デリゲートはUIPickerViewDelegateプロトコルで実装する。表示項目内容はここで返すようにする。
UIPickerViewDelegate
| メソッド名 | 動作 |
| -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component |
指定行項目の文字列を返す
|
| -(CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component | 行高さを返す |
| - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component | 列幅を返す |
| -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component |
行が選択されたときに呼び出される |
| -(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view |
指定行項目中の指定列のビューを返す
|
// プロトコルの実装
@interface hoge : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
{
~
}
// UIPickerView設定
UIPickerView *piv = [[[UIPickerView alloc] init] autorelease];
piv.center = self.view.center; // ビューの中央に表示;これはUIViewのプロパティ
piv.delegate = self; // デリゲートを自分自身に設定
piv.dataSource = self; // データソースを自分自身に設定
[self.view addSubview:piv];
// データソースメソッドの実装
// 列数を返す
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView
{
return(2); // 列数は2
}
// 行数を返す
-(NSInteger)pickerView:(UIPicerView*)pickerView numberOfRowsInComponent:(NSInteger)component
{
switch (component) {
case 0:
return(10); // 1列目は10行
case 1:
return(5); // 2列目は5行
}
}
// デリゲート
-(NSString*)pickerView:(UIPickerView*)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [NSString stringWithFormat:@"%d", row]; // 行番号を表示する
}
Navigationと組み合わせ、遷移先画面で同一UIPickerViewインスタンスで項目を入れ替えて使おうと思ってもうまくいかない。
項目は(UIPickerViewを動かせば)変化するので、Navigationが表示内容をキャッシュしているのかもしれない。
基本的に、ビューが変わったときは、制御するインスタンスも換えろと言うことであろう。
UIDatePicker
日時ピッカーのUIDatePickerは、カレンダーアプリなどで、くるくる回して日付や日時を選択するビューである。
UIDatePicker
| プロパティ名 | 属性 | 内容 |
| NSCalendar *calendar | C | date pickerで使うカレンダーを設定する |
| NSDate *date | T | 表示されている日時 |
| UIDatePickerMode datePickerMode | | 表示モード(表示順はロケールに従う)
UIDatePickerMode(enum値)
| UIDatePickerModeTime | 時、分、オプションでAM/PM |
| UIDatePickerModeDate | 年、月(フル表示)日 |
| UIDatePickerModeDateAndTime | 月(省略表示)、日、曜日(省略表示)、時、分、AM/PM |
| UIDatePickerModeCountDownTimer | 時、分(カウントダウンタイマーモード) |
|
| NSTimeInterval countDownDuration | | カウントダウンタイマー有効時のカウントタウン秒数 |
| NSLocale *locale | T | ロケール設定 |
| NSDate *maximumDate | T | 表示可能最大日付(nil=制約なし) |
| NSDate *minimumDate | T | 表示可能最小日付(nil=制約なし) |
| NSInteger minuteInterval | | 時間の設定間隔(1~30で60を割りきれる数であること) |
| NSTimeZone *timeZone | T | タイムゾーン |
| メソッド名 | 動作 |
| -(void)setDate:(NSDate *)date animated:(BOOL)animated | 表示する日付を設定する(アニメーション指定付き) |
UIWebView
UIWebViewは、Webページを管理するビューである。
このクラスは子クラスにはなれない。
UIWebView
| プロパティ名 | 属性 | 内容 |
| id <UIWebViewDelegate> delegate | S | デリゲートを設定する |
| BOOL loading | RG=isLoading | 内容を読み込み終了したかどうか |
| NSURLRequest *request | RT | 表示したいURL |
| BOOL scalesPageToFit | | Webページをビューに合わせて表示し、その大きさを変更できるかどうか
(NO=ズーム不可;デフォルト、YES=ズーム可能)
|
| BOOL allowsInlineMediaPlayback | | HTML5動画をインライン再生するか、フルスクリーンコントローラーを使うか |
| BOOL canGoBack | RG=canGoBack | 前ページに戻れるかどうか |
| BOOL canGoForward | RG=canGoForward | 後ページに移動できるかどうか |
| UIDataDetectorTypes dataDetectorTypes | | Webの特定用をクリック可能なURLに変換するかどうか |
| BOOL mediaPlaybackRequiresUserAction | | HTML5動画を自動再生するか要求によって再生するか |
| メソッド名 | 動作 |
| -(void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL
| メインページの内容、MIMEタイプ、文字エンコード、ベースURLを設定する
|
| -(void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL | HTMLの内容を文字列で設定する |
| -(void)loadRequest:(NSURLRequest *)request | 指定URLを非同期読み込みする |
| -(void)reload | 現在ページを再読込する |
| -(void)stopLoading | 読み込みを中断する |
| -(void)goBack | 前ページに戻る |
| -(void)goForward | 次ページに進む |
| -(NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script | JavaScriptの実行結果を得る |
デリゲートは
UIWebViewDelegate
プロトコルで実装する。
| メソッド名 | 動作 |
| -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
| 内容読み込みに失敗したとき
|
-(BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest*)request
navigationType:(UIWebViewNavigationType)navigationType
| 内容用読み込みを開始する前
UIWebViewNavigationType(enum値)
| UIWebViewNavigationTypeLinkClicked | リンクがクリックされた |
| UIWebViewNavigationTypeFormSubmitted | ユーザーがフォームで承認した |
| UIWebViewNavigationTypeBackForward | 戻る/進むボタンが押された |
| UIWebViewNavigationTypeReload | リロード |
| UIWebViewNavigationTypeFormResubmitted | ユーザーがフォームで再承認した |
| UIWebViewNavigationTypeOther | その他 |
|
| -(void)webViewDidFinishLoad:(UIWebView *)webView
| ページの読み込みが終了したとき
|
| -(void)webViewDidStartLoad:(UIWebView *)webView
| ページの読み込みが開始されたとき
|
UIWebView *wv = [[UIWebView alloc] init];
wv.frame = CGRectMake(0, 0, 200, 300);
wv.scalesPageToFit = YES;
[self.view addSubview:wv];
NSURL *url = [NSURL URLWithString:@"http://www.google.co.jp"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[wv loadRequest:req];
テキスト表示;UITextView
テキストを表示や編集するビューである。複数行にわたることができる。
Text and Web Programming Guide for iOSも参照のこと。
UITextView
| プロパティ名 | 属性 | 内容 |
| id <UITextViewDelegate> delegate | S | 編集用のデリゲートを設定する |
| BOOL editable | G=isEditable | 編集の可否を設定する(YES=編集可/NO=編集不可) |
| NSString *text | C | テキストを設定する |
| UITextAlignment textAlignment | | 文字揃えを設定する |
| UIColor *textColor | T | テキストの色を設定する |
| UIFont *font | T | フォントを設定する |
| UIDataDetectorTypes dataDetectorTypes | | テキスト表示中で、クリック可能な文字列にするデータ形式の指定
UIDataDetectorTypes(enum値)
| UIDataDetectorTypePhoneNumber | 電話番号 |
| UIDataDetectorTypeLink | URL文字列 |
| UIDataDetectorTypeAddress | 住所 |
| UIDataDetectorTypeCalendarEvent | カレンダーイベント |
| UIDataDetectorTypeNone | なし |
| UIDataDetectorTypeAll | 全て |
|
| NSRange selectedRange | | レシーバーの現在選択範囲 |
| メソッド名 | 動作 |
| -(void)scrollRangeToVisible:(NSRange)range | 指定された範囲のテキストが見えるまで、レシーバーをスクロールする |
| -(BOOL)hasText | レシーバーが文字列を含むかどうか(YES=あり) |
IBでTextに入力する際、改行は「Option+Enter」で行う。Enterだけを押すと、入力を終了してしまう。
編集に関する制御は、
UITextViewDelegate
プロトコルで実装する。
全てオプション扱いである。
| メソッド名 | 動作 |
| -(BOOL)textViewShouldBeginEditing:(UITextView *)textView | 編集開始を知らせるかどうか |
| -(BOOL)textViewShouldEndEditing:(UITextView *)textView | 編集終了を知らせるかどうか |
| -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text |
テキスト変更可能かどうか |
| -(void)textViewDidBeginEditing:(UITextView *)textView | テキストが編集開始されたことを知らせる |
| -(void)textViewDidEndEditing:(UITextView *)textView | テキストが編集終了されたことを知らせる |
| -(void)textViewDidChange:(UITextView *)textView | テキストもしくは属性が変更されたことを知らせる |
| -(void)textViewDidChangeSelection:(UITextView *)textView | テキストの一部が指定されたテキストビューに変更されたことデリゲートする |
テキスト編集;UITextField
テキストフィールドは、1行のテキストを編集するビューである。
Text and Web Programming Guide for iOSも参照のこと。
UITextField
| プロパティ名 | 属性 | 内容 |
| id <UITextFieldDelegate> delegate | S | 編集用のデリゲートを設定する |
| NSString *text | C | テキスト |
| NSString *placeholder | C | テキストフィールドに何も入力されていないときに表示する文字列 |
| BOOL editing | RG=isEditing | テキストフィールドが現在編集可能かどうか |
UITextFieldDelegate
| メソッド名 | 動作 |
| -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField | 編集開始を知らせるかどうか |
| -(BOOL)textFieldShouldEndEditing:(UITextField *)textField | 編集終了を知らせるかどうか |
| -(void)textFieldDidBeginEditing:(UITextField *)textField | テキストフィールドが編集開始されたことを知らせる |
| -(void)textFieldDidEndEditing:(UITextField *)textField | テキストフィールドが編集終了されたことを知らせる |
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string |
テキスト変更可能かどうか |
| -(BOOL)textFieldShouldClear:(UITextField *)textField | 入力削除を知らせるかどうか(clearsOnBeginEditingプロパティ=YES時) |
| -(BOOL)textFieldShouldReturn:(UITextField *)textField | リターンボタンが押されたことを知らせるかどうか |
テキストがキーボードで隠れてしまう様な時でも、システムは特に何も処理はしてくれないので、
スクロールアップするか、表示を移動するかの処理を入れなければならない。
他のボタンを叩いたときにキーボードを消す等の処理もユーザーに任されている。
UIImage
1枚の画像を保持するクラスである。表示は
UIImageViewで行う。
UIImage
| プロパティ名 | 属性 | 内容 |
| UIImageOrientation imageOrientation | R | 画像の表示方向(回転向き)を取得する
Readonlyなので設定はできない。では誰が設定するのかというと、JPEGのExif情報に従うらしい。
UIImageOrientation(enum値)
| UIImageOrientationUp | 通常 |
| UIImageOrientationDown | 上下逆 |
| UIImageOrientationLeft | 左90度回転 |
| UIImageOrientationRight | 右90度回転 |
| UIImageOrientationUpMirrored | 左右逆(鏡像) |
| UIImageOrientationDownMirrored | 上下逆鏡像 |
| UIImageOrientationLeftMirrored | 左90度鏡像 |
| UIImageOrientationRightMirrored | 右90度鏡像 |
|
| CGSize size | R | 画像サイズを取得する |
| CGFloat scale | R | 画像の表示倍率を指定する
PNG/JPEGフォーマットのみ
デフォルトは1.0(等倍)
ファイル名内に@"2x"という修飾子がある場合は2.0になる
|
| CGImageRef CGImage | R | メモリ上の画像データがメモリ不足のために破棄されたとき、リロードする |
| メソッド名 | 動作 |
| +(UIImage *)imageNamed:(NSString *)name | メインバンドル内から指定ファイルの画像を読み込む。サポートする画像形式は後述。
|
+(UIImage *)imageWithContentsOfFile:(NSString *)path
-(id)initWithContentsOfFile:(NSString *)path | 指定パスの画像を読み込む
|
+(UIImage *)imageWithData:(NSData *)data
-(id)initWithData:(NSData *)data | NSData内のデータで初期化する
|
+(UIImage *)imageWithCGImage:(CGImageRef)cgImage
-(id)initWithCGImage:(CGImageRef)cgImage | CGImageRefクラスの画像で初期化する
|
+(UIImage *)imageWithCGImage:(CGImageRef)cgImage scale: orientation:
-(id)initWithCGImage:(CGImageRef)cgImage scale:orientation: |
CGImageRefクラスの画像を倍率、方向を指定して初期化する
|
| -(void)drawAtPoint:(CGPoint)point | カレントコンテント内の指定位置に画像を貼り付ける
カレントコンテントとは、現在表示または出力対象になっている画面または仮想画面のことである。
|
| -(void)drawAtPoint:(CGPoint)point blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha |
カレントコンテント内の指定位置に画像を貼り付ける(合成モード、α値指定付き) |
| -(void)drawInRect:(CGRect)rect | カレントコンテント内の指定された領域をパターンで埋め尽くす |
| -(void)drawInRect:(CGRect)rect blendMode: alpha | カレントコンテント内の指定された領域をパターンで埋め尽くす(合成モード、α値指定付き) |
| -(void)drawAsPatternInRect:(CGRect)rect | カレントコンテント内に指定された大きさの画像のパターンを設定する |
CGBlendModeとは、画像を重ね合わせするときのモードのことである。詳細は分からないので、試して理解するしかない。
Adobe PhotoShopにはレイヤーごとの重ね合わせモードがあるが、
それは元来この設定モードを使っただけである(少なくとも最初はそうだったらしい。現在も全く同じだかは分からないけど)。
CGBlendMode
(enum値)
| kCGBlendModeNormal | 合成しない(上書き) |
| kCGBlendModeMultiply | 乗算 |
| kCGBlendModeScreen |
| kCGBlendModeOverlay |
| kCGBlendModeDarken |
| kCGBlendModeLighten |
| kCGBlendModeColorDodge |
| kCGBlendModeColorBurn |
| kCGBlendModeSoftLight |
| kCGBlendModeHardLight |
| kCGBlendModeDifference |
| kCGBlendModeExclusion |
| kCGBlendModeHue |
| kCGBlendModeSaturation |
| kCGBlendModeColor |
| kCGBlendModeLuminosity |
| kCGBlendModeClear |
| kCGBlendModeCopy |
| kCGBlendModeSourceIn |
| kCGBlendModeSourceOut |
| kCGBlendModeSourceAtop |
| kCGBlendModeDestinationOver |
| kCGBlendModeDestinationIn |
| kCGBlendModeDestinationOut |
| kCGBlendModeDestinationAtop |
| kCGBlendModeXOR | 排他的論理和 |
| kCGBlendModePlusDarker |
| kCGBlendModePlusLighter |
サポートされている画像ファイルは以下の通りである。
| フォーマット名 | 拡張子 |
| TIFF | .tiff, .tif |
| JPEG | .jpg, .jpeg |
| GIF | .gif |
| PNG | .png |
| Windows Bitmap Format | .bmp, .BMPf |
| Windows Icon Format | .ico |
| Windows Cursor | .cur |
| XWindow bitmap | .xbm |
CGImageRefは、主にQuickDrawの描画関数で生成できるビットマップ・イメージを管理する構造体である。
QuickDraw関数で描画した画像はUIImageに変換してiOSに渡すというのが常套手段となる。
CGImageRef
CGImageRef CGImageCreate (
size_t width, // 画像横幅(ピクセル数)
size_t height, // 縦幅
size_t bitsPerComponent, // ピクセル1色の構成ビット数(8bitとか)
size_t bitsPerPixel, // 1ピクセルの構成ビット数(全色での合計ビット数)
size_t bytesPerRow, // ビットマップの水平1行のバイト数
CGColorSpaceRef colorspace, // 画像のための色空間(Quartzは渡した色空間を保持する)
CGBitmapInfo bitmapInfo, // ビットマップがピクセルでアルファ・チャンネルとその相対的な場所を含まなければならないかどうかについて指定するCGBitmapInfo定数
CGDataProviderRef provider, // ビットマップデータ源
const CGFloat decode[], // 画像の色変換のための指定配列(NULL=変換なし)
bool shouldInterpolate, // 補間が必要かどうか
CGColorRenderingIntent intent // 表示できない色に関する処理方法の指定(Quartz)
);
//画像ファイル名を指定したUIImageの生成
UIImage *image = [UIImage imageNamed:@"Sample.png"];
//URLを指定したUIImageの生成
NSData *dt = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://xxx/aa.png"]];
UIImage *image = [[UIImage alloc] initWithData:dt];
UIScrollView
UIScrollViewは、その名の通り画面のスクロールを行うビューである。
UIScrollView
| プロパティ名 | 属性 | 内容 |
| id <UIScrollViewDelegate>delegate | S | デリゲートを設定する |
| CGPoint contentOffset | | スクロール画面の初期位置を設定する |
| UIEdgeInsets contentInset | | コンテントビューのスクロールビューからのインセット距離を設定する |
| CGSize contentSize | | スクロール画面全体のサイズを設定する(表示サイズではない) |
| BOOL dragging | RG=isDragging | スクロールし始めたかどうか |
| float maximumZoomScale | | ピンチアウト等で拡大したときの最大拡大倍率を設定する |
| float minimumZoomScale | | ピンチイン等で縮小したときの最小縮小倍率を設定する |
| BOOL pagingEnabled | G=isPagingEnabled | ページ単位スクロールを設定する;YES=可能、NO=不可(デフォルト) |
| BOOL scrollEnabled | G=isScrollEnabled | スクロールが有効かどうか |
| BOOL scrollsToTop | | スクロール・トゥ・トップを有効にするかどうか |
| float zoomScale | | ズーム率を設定する。デフォルト=1.0 |
| BOOL zoomBouncing | RG=isZoomBouncing | ズームがレシーバーに指定されたズーム率限度を上回った |
| BOOL zooming | RG=isZooming | 内容ビューが現在ズームYES しているかどうか(NO=通常表示) |
| BOOL tracking | RG=isTracking | ユーザーがスクロールを始めるために内容に触ったかどうか |
| BOOL showsHorizontalScrollIndicator | | 水平スクロールバーを表示するかどうか |
| BOOL showsVerticalScrollIndicator | | 垂直スクロールバーを表示するかどうか |
| UIEdgeInsets scrollIndicatorInsets | | スクロールインジケーターの表示位置をビュー内のインセットで設定する |
| メソッド名 | 動作 |
| -(void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated | 内容の特定領域を見えるようにスクロールする |
| -(void)zoomToRect:(CGRect)rect animated:(BOOL)animated | 内容の特定領域が見えるように拡大する |
| -(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view |
内容をタッチダウンしたときのデフォルト動作を子クラスでオーバーライドする
|
スクロールビューは、特定動作時にデリゲートを呼び出す。
UIScrollViewDelegate
| メソッド名 | 動作 |
| -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView |
ズーム対象のUIViewを返す(拡大しないときはnilを返す);ズームをするには必須 |
| -(void)scrollViewDidScroll:(UIScrollView *)scrollView | スクロールした |
| -(BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView | 内容先頭にスクロールする |
| -(void)scrollViewDidScrollToTop:(UIScrollView *)scrollView | 先頭にスクロールした |
| -(void)scrollViewDidZoom:(UIScrollView *)scrollView | 拡大率を変更した |
| -(void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView*)view | 拡大を始めようとしている |
| -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale | 拡大が終わった |
| -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView | スクロールが開始される |
| -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate | スクロール終端でドラッグされた |
| -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView | スクロールビューのスクロールアニメーションが終わった |
viewForZoomingInScrollViewはちょいとわかりにくいので補足。
-(UIView *)viewForZoomingInScrollView:(ScrollView *)scrollView_
// UIScrollViewのデリゲート:ズーム対象のUIViewを返す
// これがないとズームしない(読み出し時はzoom=1.0になってしまい、書き込み時は無視される)
// ズーム前に呼び出される
{
NSLog(@"viewForZoomingInScrollView:%@",scrollView_);
// この中でzoom関連値をいじると再帰呼び出しになって無限ループに入ってしまうので注意
// ちょっと高度そうな書き方
for (id subview in scrollView_.subviews) { // subviewsはUIViewのプロパティ
// scrollView内にあるUIImageViewのみをズーム対象としたいとき(UIViewはズーム対象にしない)
if ([subview isKindOfClass:[UIImageView class]]) {
// NSLog(@"subview=%@",subview);
return subview;
}
}
#if 0 // もちろん直接対象としたいビューと比較しても構わない
if (scrollView_==tehonScrollView ) {
return tehonImageView;
}
#endif
// ズーム禁止中
return nil;
}
iOSのズームにはバグがいて、拡大するとcontentSizeを超える領域までスクロール出来なくなる。
そのため、ズーム時にはそれも拡大するという処理を通さなければならない。
CGSize orgSize=self.contentSize; // 倍率1の時のサイズを保存しておく
~
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
// ズーム倍率変更時
zoom=self.zoomScale;
CGSize size=self.contentSize;
size.width *=zoom;
size.height*=zoom;
self.contentSize=size;
[self setNeedsDisplay]; // 再表示
}
UIActivityIndicatorView
UIActivityIndicatorViewの進行度計は、重い処理を実行するときに画面の真ん中に出るギアのような回る物である。
進行していることは示すが、それがどれくらい進んでいるかは表示しない。
UIActivityIndicatorView
| プロパティ名 | 属性 | 内容 |
| UIActivityIndicatorViewStyle activityIndicatorViewStyle | | 進行度計の形状を指定する
UIActivityIndicatorViewStyle(enum値)
| UIActivityIndicatorViewStyleWhiteLarge | 大きな白い形 |
| UIActivityIndicatorViewStyleWhite | 標準的な白い形(デフォルト) |
| UIActivityIndicatorViewStyleGray | 標準的な灰色の形 |
|
| BOOL hidesWhenStopped | | アニメーションが止まるときインジケーターを消すかどうか |
| メソッド名 | 動作 |
| -(id)initWithActivityIndicatorStyle: (UIActivityIndicatorViewStyle)style | 初期化 |
| -(BOOL)isAnimating | アニメーションするかどうか(YES=ON) |
| -(void)startAnimating | 進行度計をアニメーションさせる。 |
| -(void)stopAnimating | 進行度計のアニメーションを止める。 |
// 初期化
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
// フレームを設定
indicator.frame = CGRectMake(100.0, 100.0, 50.0, 50.0);
// 親ビューに追加
[self.view addSubview:indicator];
// 進行度計表示
[indicator startAnimating];
// インジケーターはRunLoopに入らないと表示されない(当然回らない)ので、一瞬処理をRunLoopに戻す;重要
[[NSRunLoop currentRunLoop]runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0]];
//
~重い処理
// 進行度計非表示
[indicator stopAnimating];
RunLoopのことを知らないとはまるので注意。そんなこと仕様書にも書いてなかったけどなぁ。
進行度計;UIProgressView
UIProgressView の進行度計は、途中の進行度を表示する。
UIProgressView
| プロパティ名 | 属性 | 内容 |
| float progress | | 現在の進行度を設定する |
| UIProgressViewStyle progressViewStyle | | 表示形式の設定
UIProgressViewStyle(enum値)
| UIProgressViewStyleDefault | 白地に青;デフォルト |
| UIProgressViewStyleBar | 灰色地に白;ツールバーで使われている様式 |
|
| メソッド名 | 動作 |
| - (id)initWithProgressViewStyle:(UIProgressViewStyle)style | 初期化 |
表示を変更していくには、別スレッドで並行動作させる必要がある。
@interface tmpViewController : UIViewController
{
IBOutlet UIProgressView *progressBar;
}
@property(nonatomic, retain) IBOutlet UIProgressView *progressBar;
- (IBAction)start;
- (void) progress:(NSNumber *)amount;
@end
@implementation tmpViewController
@synthesize progressBar;
- (IBAction)start
{
progressBar.progress = 0;
for (int i=0; i<100; i++) {
[self performSelectorInBackground:@selector(progress:) withObject:[NSNumber numberWithFloat:0.01f]];
[NSThread sleepForTimeInterval:0.1f];
}
}
// バックグラウンドでprogressを変更
- (void)progress:(NSNumber *)amount
{
progressBar.progress += [amount floatValue];
}
- (void)dealloc
{
[progressBar release];
[super dealloc];
}
@end
UIPageControl
ページコントロールは、ページのだいたいの位置を示す白ドットの並び表示である。
「ページインジケーターコントロール」と呼ばれることもある。
ページと書いているが、PDF等のページそのものを管理するのではなく、
その中のおおよその位置をドット位置として表す。
プロパティやメソッドの「数」もページ数ではなくドット数なので注意。
実ページからドットへの変換はユーザーが行う必要がある。
UIPageControl
| プロパティ名 | 属性 | 内容 |
| NSInteger currentPage | | 現在のページドット番号(0~) |
| BOOL defersCurrentPageDisplay | | YES=updateCurrentPageDisplayを呼び出までページ指標更新を延期する
NO=ページ指標のみ即時更新する。 |
| BOOL hidesForSinglePage | | 1ページしかないときにページ指標を隠すかどうか |
| NSInteger numberOfPages | | 全ページドット数(0~) |
| メソッド名 | 動作 |
| -(CGSize)sizeForNumberOfPages:(NSInteger)pageCount | ページドット数を納めるレシーバー境界のサイズ |
| -(void)updateCurrentPageDisplay | ページ指標を現在ページに合わせる |