2012年2月9日木曜日

UIView を使いこなそう


今回の目次
  • UIViewの種類
  • UITableViewとUINavigationContoller
  • UIImageViewとUIScrollView
iOSの画面の構成は、UIViewに溢れています。

なので、UIViewを理解することは即ち、iOSの画面構成を理解する!といっても過言ではありません。
今回は、そんなUIViewについて説明して行きます。


UIViewの種類
UIViewの種類と一口に言っても、いろいろな種類があります。
例えば、
  • 画像を保持するUIImageView
  • 文字列を表示するUILabel (前回使いました)
  • 画面のスクロールを管理するUIScrollView
  • 表を出力するUITableViewと各セルを表すUITableViewCell
などなどです。

そしてiOSの画面は、このUIViewの積み重ねで出来ています。
例えば、でかいビューがあって、その上にUIImageViewとUILabelが乗っかってて、
さらに、UIScrollViewがラップしてる、などいろんなViewが積み重なっています。
どういうViewがどうやって積み重なっているかの順序関係で時々はまったりするので、抑えておくことをお勧めします。

・UINavigationControllerによる画面遷移
iOSの画面遷移にはいろんな方法がありますが、一般的なのは、テーブルビューから横にヒュイッと移動するのが割と多いと思います。
(最近はもっと洗練された奴がでてきてたりしますが)
これは、UINavigationControllerというクラスが、管理しています。
pushViewControllerというメソッドを呼び出すと次の画面に移ります。
前の画面に戻るのは popViewControllerというメソッドです。
自分で呼び出すこともできますし、NavigationControllerも勝手にボタンを作ってくれます。



UITableViewとUINavigationController
それでは、前回と同じようにXcodeを起動して、プロジェクトを作る所から始めましょう。
今回はひな形に Master-Detail Applicationを使います。その際に、Device familyはiphoneを、Use StoryboardUse Automatic Reference Countingのチェックボックスは外しておいてください

多分、起動するとこんな画面になると思います。


Detailをクリックすると、こんな画面に行って、


Masterを押すと元に戻ると思います。

まずは、新しいViewを追加しましょう
New file NewFile として、新しいファイルを追加します。
クラステンプレートはUIViewController subclass
Target for iPadのチェックは外す
With XIB for user Interfaceのチェックはオン
としてファイルを作ります。ファイル名はなんでもいいですが、ImageViewControllerとしました。

次にMasterViewController.hを修正します。

まずクラス変数として、ImageViewController型の変数を一つ追加します。
そしてメソッドを定義する所に
@property (strong, nontoxic) ImageViewController *imgViewController;
と入れます。これは、自動的にアクセサを作ってくれるおまじないです。

では、次は.mファイルへうつります
@implementationの下に
@synthesize imgViewController;
と入れておいてください。

まずは、
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
とします。これは、テーブルが何個セルがあるかを返すメソッドです。
テンプレートファイルでは初期状態で1個あり、今から自分たちで追加するので2を返します。

次に、メソッド
(UITableViewCell *)tableView:tableView cellForRowAtIndexPath:indexPath
を修正します。if文以降を次のように変更し、次のようにします。
このメソッドは、各テーブルの一つ一つに何を表示するかを与えて返します。テーブルのセルはUITableViewCell型で、自分でいろいろといじれますが、今回は割愛します。
indexPath にどのグループの何番目のセルかという情報が入っています。
今回は0番目の列にはテンプレートのものを
1番目の列には、自分の作るものを書きました。


そしてメソッド
- tableView:(UITableView *)tableView didSelectRowAtIndexPath:indexPath

は次のように変更します。

このメソッドは、indexPathのセルが選択されたときに、何をするかを書きます。
今回は選択したら、次の画面へ遷移するようにします。
if (!self.imgViewController) {
    self.imgViewController = [[[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil] autorelease];
   }

の部分は、メンバ変数 imgViewControllerの初期化を行っています。
initWithNibNameは,@"".xib の仕組みを使って初期化しますよというメソッドです。

[self.navigationController pushViewController:self.imgViewController animated:YES];
が画面遷移を行うメソッドです。

以上を書いて実行すると、次のような画面になると思います。






UIImageViewとUIScrollView
では、このViewをいじって行きましょう.今回はUIImageViewを用いた画像の表示を行います。

まずは、プロジェクトに画像を追加します。
画像をプロジェクトにドラッグして行くと勝手に追加してくれます。簡単ですね。



ではまず、Viewの見た目と接続を行います
  1. .xibファイルの右タブのアイテムから、UIImageViewと書かれたアイテムをドラッグして、Viewにドロップします
  2. ImageViewController.hに移り,クラスImageViewControllerにメンバ変数として IBOutlet UIImageView型の変数を追加します。名前は何でも構いませんが、今回はimgViewとしました。
  3. もう一回.xibファイルに戻って,imgViewと配置したimageViewとを接続します.

これは前回とほぼ同じ内容なので簡単ですね。

では次に,コードを書いて画像を表示させましょう。
imageViewController.mに移ります。
そして,viewDidLoadメソッドを以下の行を追加します。

imgView.image = [UIImage imageNamed:@"LENNA.bmp"];

viewDidLoadは画面が呼び出されたときに呼ばれるメソッドで、
ここで画面に貼る画像を呼び出して貼付けます。
UIImageとは、画像を簡単に扱ってくれるクラスです。残念なことに低レベルな処理(画素単位の修正)などは出来ませんが。
imageNamedメソッドは@""のファイル名のファイルを読み込んでUIImageで初期化してくれるメソッドです.
読み込んだUIImageをimgViewの持つ画像のプロパティ imgView.image にセットすることでimageViewへの画像の読み込みが完了します。
めっちゃ簡単ですね。

実行するとこんな感じになると思います。



画像のアスペクト比がおかしいことになったりするので、そういった場合は
貼付ける前に
imgView.contentMode = UIViewContentModeScaleAspectFit;
とすると、画像のアスペクト比を保ったまま、ちょうど目一杯に入るように画像を調整してくれます。





ではiPhoneらしいUIの一つ、スクロールに挑みましょう
まず、.xibファイルより先ほど追加したUIImageViewを削除します。
次にScrollViewを引っ張って来て、Viewに貼付けます。


ImageViewController.hを変更しましょう
@interface ImageViewController : UIViewController
<
UIScrollViewDelegate
>
{
 IBOutlet UIImageView *imgView;
 IBOutlet UIScrollView *scrollView;
}

@end

まず,UIViewControllerの後に 
< UIScrollViewDelegate > 
を追加して、メンバ変数に UIScrollView型を追加します。

そして再び.xibファイルに戻って、変数と配置したパーツとを繋ぎます。

ではImageViewController.mを変更して行きます。
まず, viewDidLoadメソッドを次のように変更します。


今回imgViewはUIパーツの方に入っていないので、自分で初期化する必要があります。
UIImageView initWithImageメソッドは,UIImageを用いて初期化するメソッドです.

その下のscrollViewに関する設定は、
まずcontentSizeで表示するコンテンツの大きさを設定しました。今回のコンテンツは画像の大きさとしました。
そのあと,maximumZoomScaleとminimumZoomScaleでズームの範囲を設定しています.
delegateについては後ほど述べます.
そして addSubViewでスクロールビューの下にサブビューを貼付けます.


そして,次のメソッドを追加します。
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
 return imgView;
}

これは,スクロールビューでズームが行われたときに,どのビューを拡大縮小しますかというのを返すメソッドです.
今回は,imgViewを返します.
本来,このメソッドhaUIScrollViewに定義されていて,UIScrollViewが実装するはずです.
しかし,objective-Cでは定義だけして,あとはサブクラスとか利用するクラスが代わりに実装して!という宣言の仕方が
可能で,その仕組みをdelegate(デリゲート)と呼びます.

どれをデリゲートしないといけないかは,ドキュメントなどに書いてあります.


実行すると,こんな感じでスクロールできると思います.
シミュレータ上での二本指シミュレーションはoptionキーを押しながらドラッグです。




0 件のコメント:

コメントを投稿