12
12

More than 5 years have passed since last update.

UIActionSheetのボタンを動的に変化させるならaddButtonWithTitle:とbuttonTitleAtIndex:を使う

Last updated at Posted at 2013-06-15

UIActionSheetでボタンの表示を切り替えたい場合、ボタンはaddButtonWithTitle:メソッドにより表示順に追加し、クリック処理時はbuttonTitleAtIndex:メソッドでボタンタイトルにより分岐させればindexを気にしなくて良くなります。

actionsheet.001.jpg

大抵の場合、UIActionSheetのボタンが押された時の処理は、UIActionSheetDelegateのactionSheet: clickedButtonAtIndex:メソッドを実装し、引数で渡されるクリックされたボタンのindexによって処理を実行すると思います(iPhoneアプリ開発の虎の巻:http://iphone-tora.sakura.ne.jp/uiactionSheet.html )。

ただ、UIActionSheetのボタンの表示を動的に変化させる場合は、ボタンの表示順が変わるため当然indexが変わり、それを考慮する必要が出てきます。つまりUIActionSheetの生成時とそのクリック処理の条件分岐にindexを共通で変化させる必要が出てきてしまいます。

しかし、UIActionSheetの生成時は条件によって追加するボタンを変更し、クリック処理時はボタンが押されたタイトルによって条件を分岐することによって、indexの整合性を取る必要がなくなります。

例とサンプルコード

例をあげます。UIActionSheetによりお気に入りに追加する画面があるとします。お気に入りに追加済みかどうかを示すフラグself.favがYES、そうでなければNOを返し、そのフラグによってお気に入りに既に追加済みであれば「お気に入りに追加」ボタンを表示しないというケースが有るとします。

まずUIActionSheetの生成は、addButtonWithTitleメソッドで条件によって表示する/しないを決定します。

- (IBAction)showActionSheet:(id)sender
{   
    // アクションシートの作成。タイトルを設定しない
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
                                                             delegate:self
                                                    cancelButtonTitle:nil
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:nil];
    if (self.fav) {
        //すでにお気に入りに追加済みなのでお気に入りに追加という選択はない
        //ツイートするボタンのみ
        [actionSheet addButtonWithTitle:@"ツイートする"];
    } else {
        //お気に入りに登録していないのでお気に入りに追加という選択がある
        [actionSheet addButtonWithTitle:@"お気に入りに追加する"];
        [actionSheet addButtonWithTitle:@"ツイートする"];
    }

    //最後にcancelボタンを追加しボタン総数から1減らした数をindexにする
    [actionSheet addButtonWithTitle:@"キャンセル"];
    actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1;

    // アクションシートの表示
    [actionSheet showInView:self.view];
}

次に処理を行うメソッドでは、buttonTitleAtIndex:メソッドを使いUIActionSheetからクリックされたボタンのタイトルを取得、そのタイトルによって処理を分岐します。

//UIActionSheetDelegateによるクリック時処理
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *clieckedButtonTitle = [actionSheet buttonTitleAtIndex:buttonIndex];

    if ([clieckedButtonTitle isEqualToString:@"お気に入りに追加する"]) {
        //お気に入りに登録する処理実行
        /*…*/
    } else if ([clieckedButtonTitle isEqualToString:@"ツイートする"]) {
        //ツイートする処理実行
        /*…*/
    }
}

(上記の例ではタイトルの文字列をハードコーディングしていますが、状況によって定数やプロパティを使えばよいでしょう)

これによって、順番を気にするのは生成時のみで、処理を行うメソッドでは動的に変化するindexやお気に入りに追加済みフラグを加味しなくてもよくなっているのがわかると思います。

メリットデメリット

メリット
・クリック時にボタン表示順による分岐処理が不要になる
・クリック時にボタン表示/非表示フラグによる分岐処理が不要になる

デメリット
・Viewであるボタンのタイトルの文字列で処理を分けるのが若干気持ち悪い

何か他にも良い方法があればコメントにお願いします。

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12