A view can only be associated with at most one view controller at a time!エラー
幾つかの画面(ViewController)で共通のUIActionSheetを使い回したかったので共通のUIActionSheetを管理するシングルトンクラスを生成して、そのシングルトンクラスのUIActionSheetを表示させたいViewControllerでshowFromBarButtonItemしていた。
iPadではBarButtonItemを再度押したら表示しているUIActionSheetを消すという処理を実装してあげないといけないので、その処理を書いたら下記エラーが発生した。
'A view can only be associated with at most one view controller at a time! View
1つのViewは1つのViewControllerにしか所属できないよということ。
UIActionSheetは実は_UIActionSheetHostingControllerというControllerに既に所属している?らしい。
これを回避するには共通で使用したいUIActionSheetを使うViewController内でUIActionSheetのインスタンスを作成しておき、そのインスタンスに共通で使用したいUIActionSheetを代入するとエラーを回避できる。
//共通で使い回すUIActionSheetを管理するシングルトンクラス [ASManager.h] @interface ASManager : NSObject @property (readonly, nonatomic) UIActionSheet *as; + (ASManager *)sharedManager; @end [ASManager.m] @interface ASManager () @property (retain, nonatomic) UIActionSheet *as; @end @implementation ASManager + (ASManager *)sharedManager { static ASManager *sharedManager; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedManager = [[ASManager alloc] init]; }); return sharedManager; } - (id)init { self = [super init]; if (self) { //共通で使い回したいUIActionSheet作成 _as = [[UIActionSheet alloc] init]; _as.title = @"選択してください" [_as addButtonWithTitle:@"A"]; [_as addButtonWithTitle:@"B"]; [_as addButtonWithTitle:@"C"]; [_as addButtonWithTitle:@"キャンセル"]; _as.cancelButtonIndex = 3; _as.delegate = self; } return self; } - (void)dealloc { _as.delegate = nil; [_as release]; [super dealloc]; } #pragma mark - UIActionSheetDelegate - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { //選択された各ボタンに応じて処理を書く switch (buttonIndex) { case 0: break; case 1: break; case 2: break; default: return; break; } } @end
このシングルトンを使用するViewControllerクラスのエラー発生Verメソッド
//UIBarButtonの押下がトリガーとなり呼ばれるメソッド - (IBAction)useASManagerActionSheet:(id)sender { //閉じる処理 if ([ASManager sharedManager].as.visible) { //ここで本題のエラーが発生する [[ASManager sharedManager].as dismissWithClickedButtonIndex:-1 animated:YES]; return; } //シングルトンのUIActionSheetを直接使用 [[ASManager sharedManager].as showFromBarButtonItem:sender animated:YES]; }
エラー回避Ver.
前提として@interface部でUIActionSheetのインスタンスas変数が定義しているものとする
//UIBarButtonの押下がトリガーとなり呼ばれるメソッド - (IBAction)useASManagerActionSheet:(id)sender { //閉じる処理 if (_as.visible) { [_as dismissWithClickedButtonIndex:-1 animated:YES]; return; } //シングルトンのUIActionSheetを定義したインスタンスに代入して使ってあげる _as = [ASManager sharedManager].as; [_as showFromBarButtonItem:sender animated:YES]; }
こうすればdismissWithClickedButtonIndexした時にクラッシュしなくなる。
参考
http://program.station.ez-net.jp/special/objective-c/xcode/build-error/view-controller.asp