iPhone アプリ開発でActivityIndicatorをカスタマイズする



Loading

さてさて、iPhone アプリなんかを作っていると、バックグラウンドでの処理中には、Loading マークを出して、処理中であることをユーザーに知らせたい場合は多々あるだろう。
そんなときには、"ActivityIndicator" を使えばいいんだけれども、これだけを使うと、背景がいろいろとごちゃごちゃしている場合なんかには、見えにくくなってしまったり、オブジェクトの前後関係の設定が難しくて、背景に隠れてしまったりとどうも、思うようには成らない場合が多い。


カスタマイズ

そんなときには、カスタマイズをしたくなるのだけれども、通常の機能だけでは、この"ActivityIndicator"はなかなかうまくカスタマイズ出来ない。
ということで、今回は、その"ActivityIndicator"のカスタマイズ方法をご紹介したい。


ターゲット

最終的にできあがるのは、下記のような状況。
"Loading"というテキストの横に "ActivityIndicator" が動いていて、そして、それらを白線の枠と灰色の背景を持つ箱の中に納めているというもの。





準備

ということで、まずは準備です。この Loading マークの構成要素は、それぞれ下記で作ります。


・テキスト・・・UILabel
・ActivityIndicator・・・UIActivityIndicatorView
・箱・・・UIView


ということで、対象の .h ファイルの @interface の中に下記を記述します。

    UILabel *loadingLabel;
    UIActivityIndicatorView *loadingMark;
    UIView *loadingContainer;



コード

続いて、これらを利用して書いていきますので、 .m ファイルの例えば、"- (void)viewDidLoad" の中に以下を記述します。

    /////
    //Set Loading Mark
    /////
    loadingContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 60)];
    
    //Set Style Of Label
    loadingLabel = [[UILabel alloc] init];
    loadingLabel.text = @"Loading";
    loadingLabel.textColor = [UIColor whiteColor];
    loadingLabel.shadowColor = [UIColor blackColor];
    loadingLabel.shadowOffset = CGSizeMake(1, 1);
    loadingLabel.font = [UIFont boldSystemFontOfSize:17];
    loadingLabel.backgroundColor = [UIColor lightGrayColor];
    loadingLabel.frame = CGRectMake(20, 17, 70, 25);
    [loadingContainer addSubview:loadingLabel];
    
    //Set Style Of Mark
    loadingMark = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    loadingMark.frame = CGRectMake(100, 14, 30, 30);
    [loadingContainer addSubview:loadingMark];
    
    //Set Style Of Container
    loadingContainer.backgroundColor = [UIColor lightGrayColor];
    [[loadingContainer layer] setCornerRadius:8.0f];
    [[loadingContainer layer] setMasksToBounds:YES];
    [[loadingContainer layer] setBorderWidth:0.5f];
    [[loadingContainer layer] setBorderColor:[[UIColor darkGrayColor] CGColor]];
    CGRect rect = self.view.frame;
    loadingContainer.center = CGPointMake(rect.size.width/2, rect.size.height/2 * 0.8);
    [self.view addSubview:loadingContainer];
    loadingContainer.hidden = YES;



解説

これを順番に説明していきます。


箱の準備
まずは、全体を包む箱の定義です。横150、縦60の箱を準備。ここは、好みでサイズを変えればいいでしょう。

 loadingContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 60)];



テキストの書式設定
次に、その中に入れるテキストの書式を設定します。
これは、特に複雑なことはなく、初期化してその中のテキスト文字列を設定。その後は、文字色やサイズなどの定義をしていく。あとは、箱の中での位置を定義してから、箱の中に足せばおわり。
ちょいとややこしいのは、位置の設定くらいかな。(20, 17, 70, 25) は、用意している箱の中でどの位置にどのサイズで設置するか。これは、実際にコードを動かしながら、少しずつ調整するのが結局一番簡単な気がします。

    //Set Style Of Label
    loadingLabel = [[UILabel alloc] init]; //初期化
    loadingLabel.text = @"Loading"; //文字列設定
    loadingLabel.textColor = [UIColor whiteColor]; //文字色設定
    loadingLabel.shadowColor = [UIColor blackColor]; //影色設定
    loadingLabel.shadowOffset = CGSizeMake(1, 1); //影位置設定
    loadingLabel.font = [UIFont boldSystemFontOfSize:17]; //文字サイズ設定
    loadingLabel.backgroundColor = [UIColor lightGrayColor]; //背景色設定
    loadingLabel.frame = CGRectMake(20, 17, 70, 25); //位置の設定
    [loadingContainer addSubview:loadingLabel]; //上記で設定した箱の中に追加



インジケーターの設定
次は、"ActivityIndicator"の設定。
こちらも初期化とスタイル(好みでいくつか設定可能)を設定をして、あとは、テキストと同じ感じで、箱の中での位置を定義してから、箱の中に足せばおわり。

    //Set Style Of Mark
    loadingMark = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; //初期化とスタイルの定義
    loadingMark.frame = CGRectMake(100, 14, 30, 30); //位置の設定
    [loadingContainer addSubview:loadingMark]; //上記で設定した箱の中に追加



箱の設定
最後は、箱の設定。すでに初期化しているので、後は背景色だとか角丸だとか枠線の色や幅などを好みで設定する。
ちなみに角丸の設定などのためには、.m 冒頭に下記の記述が必要になります。

#import <QuartzCore/QuartzCore.h>



あとは、メイン画面に対する設置位置を決めて、実際にメイン画面へ登録。
iPhone のバージョンによって画面サイズが違うので、ここでは、数式によって、設置位置を決めています。
Loading マークの場合は、通常は最初は非表示で作業が始まったら表示するので、非表示設定にしておきます。

    //Set Style Of Container
    loadingContainer.backgroundColor = [UIColor lightGrayColor]; //背景色の設定
    [[loadingContainer layer] setCornerRadius:8.0f]; //角丸Rの設定
    [[loadingContainer layer] setMasksToBounds:YES];
    [[loadingContainer layer] setBorderWidth:0.5f]; //枠線幅の設定
    [[loadingContainer layer] setBorderColor:[[UIColor darkGrayColor] CGColor]]; //枠線色の設定
    CGRect rect = self.view.frame;
    loadingContainer.center = CGPointMake(rect.size.width/2, rect.size.height/2 * 0.8); //全体画面の中の位置の設定
    [self.view addSubview:loadingContainer];  //メイン画面への登録
    loadingContainer.hidden = YES;  //最初は、非表示設定にする



動作させる

ということで、これで、"ActivityIndicator" の初期設定は完了です。
あとは、これを適切なタイミングで動かせばいい。

    [loadingMark startAnimating]; //アニメーションスタート
    loadingContainer.hidden = NO; //非表示を解除
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; //上部のバーの"ActivityIndicator"も動かす。



ついでに、終わるときは、下記です。

    [loadingMark stopAnimating]; //アニメーションストップ
    loadingContainer.hidden = YES; //非表示化
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; //上部のバーも停止



別スレッド

なお、"ActivityIndicator"を動作させるためには、プログラム上では別スレッドに移動しないといけません。
本来は、処理が含まれるサブルーチンをスレッドでキックさせて、その直前のところで、"ActivityIndicator"を動作させることになります。
しかし、ちょっと変化球な手段としては、"ActivityIndicator"を動かすためのサブルーチンを作っておいて、それをスレッドでロードするという姑息な手段も使えます。

//ローディングマーク表示用のサブルーチン
-(void)startLoading
{
    [loadingMark startAnimating];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    loadingContainer.hidden = NO;
}

//プログラム上でローディングマークが必要になったときにこれをスレッドでキッ
      [NSThread detachNewThreadSelector:@selector(startLoading) toTarget:self withObject:nil];



以上

というような感じで、任意のローディングマークを作ることが出来ました。
結構プログラム上でレイアウトするのって大変そうな気もしますが、意外と簡単ですよね。いろいろとトライするといろいろと楽しくなって来ると思います。


関連リンク:
Xcode Downloads and Resources - Apple Developer
関連サーチ:
ActivityIndicator(AMAZON.co.jp)
ActivityIndicator(Google)
Powered BY AmazoRogi

初めてのiOSプログラミング 第2版
発売日 : 2012-10-20 (大型本)
売上ランク : 202638 位 (AMAZON.co.jp)
¥ 3,360 在庫あり。
Powered BY AmazoRogi Data as of 2013-08-15
See detail & latest visit AMAZON.co.jp