スタート画面以外でViewDeckが使えない

このQ&Aのポイント
  • Objective-CでViewDeckというライブラリを導入しようとしていますが、スタート画面以外で利用する際に問題が発生しています。
  • CenterViewControllerとLeftViewControllerを作成し、DeckViewControllerでそれらを読み込んでいます。しかし、ビルドするとCenterViewControllerを表示しようとすると真っ暗な画面が表示されます。
  • 原因としては、初期化コードに問題がある可能性があります。対策としては、初期化コードを再確認し、必要な設定を追加することです。
回答を見る
  • ベストアンサー

スタート画面以外でViewDeckが使えない

いつもお世話になっています。 現在、http://atmarkplant.com/viewdeckstoryboard-use/のページを参考にObjective-Cで"VewDeck"というライブラリを導入しようとしています。 AppDelegateに実装しスタート画面に導入することはできたのですが、スタート画面以外で利用しようとするとうまくできません。 【やったこと】 CenterViewController(IIViewDeckControllerを拡張) LeftViewController DeckViewController(IIViewDeckControllerを拡張) の3つをつくる。 CenterViewController LeftViewController にはそれぞれstoryboardIDをつける(centerとleft) DeckViewControllerでCenterViewController.hとLeftViewController.hを読み込み、以下のように実装。 - (id)initWithCoder:(NSCoder *)aDecoder { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; CenterViewController *centerController = [storyboard instantiateViewControllerWithIdentifier:@"center"]; LeftViewController *leftController = [storyboard instantiateViewControllerWithIdentifier:@"left"]; self = [super initWithCenterViewController:centerController leftViewController:leftController]; self.centerhiddenInteractivity = IIViewDeckCenterHiddenNotUserInteractiveWithTapToClose; // Disable touch event when switch other view. self.viewDeckController.bounceOpenSideDurationFactor = 0.3f; if (self) { // Add any extra init code here } return self; } 【結果】 ビルドしCenterViewControllerを表示しようとすると真っ暗な画面が表示される。 どのような原因、対策が考えられるでしょうか。 お力を貸していただけるとありがたいです。 よろしく御願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

No.1,2です。 > DeckViewControllerの生成/遷移は(a),(b)の両方で試してみましたがともに同じ結果になりました。 それ以上は試してみないとわからないので、 私もちょっと試してみました。 すると同じようにいきなりLeftViewControllerが表示されてしまいます。 ただ、画面の回転ロックを外し、端末を横にしてまた戻すと、 正しく表示されるようになりますので、ライブラリの画面遷移処理に 問題があってLeftViewControllerが表示されたままになっている ような感じがしました。 ちなみに、試しに、ナビゲーションコントローラーをつけて、 push segueで画面遷移するとうまく表示されました。 なんとなく、そのライブラリはmodal画面遷移に問題が あるような気がしましたが、それ以上はよく調べてないので わかりません。

katsuo777
質問者

お礼

わざわざそこまでしていただいて、ありがとうございます。 自分の方でもやってみましたが確かに、画面の向きを変えた時に元どおりになることはあるようですね。 pushだけで実装するか、あるいは似た機能の他のライブラリを使うことも視野に入れて考えてみます。 本当にありがとうございました。

その他の回答 (2)

回答No.2

> 例えばFirstViewControllerというようなViewControllerを新しくつくり、ボタンアクションでDeckViewControllerへの遷移を実装すると、CenterViewControllerではなくいきなりLeftViewControllerが表示されてしまいます。 この場合、DeckViewControllerの生成/遷移はどうやっているんですか? 主に3種類の方法があると思います。 (a)storyboardのsegueで接続し、自動的に生成/遷移してもらう。 (b)instantiateViewControllerWithIdentifierで生成してpresentViewControllerで遷移する。 (c)[[DeckViewController alloc] init]で生成してpresentViewControllerで遷移する。 DeckViewControllerをinitWithCoderで初期化しているなら、 (a)か(b)の方法じゃないとinitWithCoderは呼ばれませんよ。 (c)の方法にするならinitを実装する必要あります。 ただ、LeftViewControllerが表示されているということは、 (a)か(b)の方法でinitWithCoderが呼ばれているんだとは思いますが、 もしいずれでもなくて、既に生成済みのDeckViewControllerを 使い回して遷移したりしたら、おかしなことになるかもしれません。 まずはそのあたり、どうやって生成/遷移しているか説明してもらう必要が あります。それによって確認すべき点とか注意点とか変わってくると 思います。

katsuo777
質問者

お礼

Lchan0211bさん お早い回答ありがとうございます。 DeckViewControllerの生成/遷移は(a),(b)の両方で試してみましたがともに同じ結果になりました。 (a) [self performSegueWithIdentifier:@"showDeckView" sender:nil]; (b) DeckViewController *viewcon = [self.storyboard instantiateViewControllerWithIdentifier:@"deckView"]; [self presentViewController:viewcon animated:YES completion:nil]; よろしく御願いいたします。

回答No.1

まずはDeckViewControllerのinitWithCoderがちゃんと呼ばれているかどうか を確認して問題点を切り分けるところから始めればよいと思います。 ここが呼ばれてないなら、Storyboardに定義したDeckViewControllerを 生成しようとしてないという話だし、呼ばれているなら生成しようと したけどinitWithCoderの処理がどこか誤っているという話だと思います。 今回の質問は、黒画面が表示されたのに、上記の確認をしたか書かれてないし 前者の部分があまりしっかり説明されていないので、 なんとなく前者の問題のような気がしました。 だとすると storyboardのDeckViewControllerを「is initial View Controller」に 設定していますか? あるいは「is initial View Controller」に設定したViewControllerの クラスはDeckViewControllerにしていますか? そもそもDeckViewControllerを使う初期ViewControllerをstoryboardに 作っていますか? あとストーリーボードファイル名は"Main.storyboard"で合っていますか? (Webサイトの説明は"MainStoryboard.storyboard"を使うコーディング になっていますが、あなたの方は"Main.storyboard"を使うつもりなのですよね?)

katsuo777
質問者

お礼

Lchan0211bさん 詳しくご回答ありがとうございます。 まずお詫びしなければいけないこととして、自分にひとつ重大な間違いがあり、DeckViewControllerではなくCenterViewControllerを直接呼び出そうとしていました。 これでは黒画面が表示されて当然ですよね・・・。 >storyboardのDeckViewControllerを「is initial View Controller」に >設定していますか? >あるいは「is initial View Controller」に設定したViewControllerの >クラスはDeckViewControllerにしていますか? のご指摘通りDeckViewControllerをinitial View Controllerに指定すると正しく動作してくれました。 ありがとうございます。 答えていただいた上でさらに恐縮なのですが、もう一点ご教授いただいてもよろしいでしょうか。 DeckViewControllerではない画面からアプリをスタートしたい場合についてです。 例えばFirstViewControllerというようなViewControllerを新しくつくり、ボタンアクションでDeckViewControllerへの遷移を実装すると、CenterViewControllerではなくいきなりLeftViewControllerが表示されてしまいます。 NSLogを置いてみると、一瞬CenterViewControllerが表示されてからすぐLeftViewControllerが表示されているようなのですが。。。 ちなみに本来であればCenterViewController内のボタンが押された際に[self.viewDeckController toggleLeftViewAnimated:YES]が呼ばれて遷移するようになっています。 重ね重ねで申し訳ありませんが、なにとぞよろしくお願いします。

関連するQ&A

  • Xcodeでの画面遷移について

    Xcode5.0でアプリを作成しています。 アプリがバックグラウンドから再びアクティブになるときに画面遷移の処理をするために 以下の方法にてAppDelegateのapplicationDidBecomeActiveからView Controllerに処理を渡しています。 AppDelegate.m - (void)applicationDidBecomeActive:(UIApplication *)application { [[NSNotificationCenter defaultCenter] postNotificationName:@"applicationDidBecomeActive" object:nil]; } ViewController.m { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:@"applicationDidBecomeActive" object:nil]; } - (void)applicationDidBecomeActive { ViewController *View = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondView"]; [self presentModalViewController:View animated:YES]; } ViewController.mの- (void)applicationDidBecomeActiveで画面遷移の処理をしたいのですが、ViewDidAppearでは出来る画面遷移がapplicationDidBecomeActiveでは実行されない状態です。 ググって調べたところ、読み込みのタイミングが問題らしいことはなんとなく解ったのですが、 どうにかして、- (void)applicationDidBecomeActiveと同じタイミング(アプリがアクティブになったとき)で画面遷移を行う方法はありますでしょうか?

  • Objective-c画面推移のメモリ管理について

    iPhoneアプリ開発を初めて間もなく拙い質問ですがお願いします。 StoryBoardを使わずにxibを指定して直接画面推移を行っています。 その周辺のコードは http://www.bhnt.co.jp/blog/雑記/社員:cobra/イチから学ぶiphoneipadアプリ開発-第6回-「interface-builderを使って ...を参考にしました。 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { SecondViewController *vc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self presentViewController:vc animated:NO completion:nil]; // [self removeFromParentViewController]; // [self.view removeFromSuperview]; } 画面がタッチされたときにSecondViewControllerを呼び出して、画面を遷移しています。 SecondViewControllerにも似たコードを記述しMainViewControllerに遷移しています。 これを繰り返していると数MByteずつ使用メモリが増えていきます。まだメモリも小さく支障は全くないのですが、いずれ悩まされる前に解決したいと思い質問しました。 遷移したあとに元の画面が破棄されていないのでは無いかと思い、コメントアウトにしてある下二行を追加してみましたが、結果は変わりませんでした。 破棄されたことを示すviewDidDisappearをNSLogで確認してみたところ、呼び込まれているのですが、これはC++などでいうデストラクタとは似つかない処理でしょうか? 長々と要点の掴みづらい質問ですがどうかよろしくお願いします。

  • iPhoneアプリの開発についてです。

    元のビューからモーダルで表示させるビューに画面遷移に伴い値を受け渡したいのですがうまくいきません。 私は主に画面遷移する際 ○○○ *△△△ = [self.storyboard instantiateViewControllerWithIdentifier:@"□□□"]; [self presentViewController:△△△ animated:YES completion: nil]; とコーディングしています。 インスタンス生成部分を ○○○ *△△△ = [[○○○ alloc] init]; とすれば簡単に値が受け渡しできるのですが、storyboadで作ったような表示になりません。(セルの高さが違う、ラベルが表示されないなど) グローバル変数などを使っても解決できますが、なるべく複雑にはしたくありません。 ご指摘お願いします。

  • NavigationItemに関する質問です。

    iPhoneアプリの開発でNavigationControllerで画面遷移した後、左上に表示させる戻るボタンをカスタマイズしたいです。 実際に方法は心得ているのですが、これをAppDelegateクラスなどで一括で設定したいのですがうまくいきません。 UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = back; 上記の様に戻るなどの文字は表示せず、矢印だけの表示にするつもりです。 それぞれのViewContorollerのクラス内に書くのはかなり面倒なので、分かる方がいたら教えてくださると助かります。

  • Objective-c 画面遷移について

    やはり、画面遷移ではまっていますので、助けて下さい。 navigationControllerで作成しています。 (内容は以前に質問させて頂いているものとほぼ同じですが、) 「FirstViewController」はUIScrollViewでスクロールさせている画面で、タッチイベントを取得する為に UIScrollView のサブクラスを作っています。 そこでタッチすると、「SecondViewController」へ遷移するようにしたいのですが、下記のように単純にpushViewControllerを使ってサブクラスへ書くと、「Property 'navigationContoroller' not found on object of type 'MyScrollview'」というエラーが表示されてしまいます。 このクラスへ書いたらいけないというのは、なんとなく分かりますが、かと言って何からどう手をつければ良いのか分かりません…… 問題なく画面遷移させるにはどうしたらよいのでしょうか。 詳しく教えて頂けると、大変助かります。。 ↓FirstViewController.h↓ @interface FirstViewController : UIViewController{   MyScrollview *controller; IBOutlet UIScrollView *scrollView; } ↓FirstViewController.m↓ - (void)viewDidLoad { controller = [[ MyScrollview alloc] initWithFrame:CGRectMake(0, 0, 1100, 1100)]; self.view = controller; [super viewDidLoad]; [super loadView]; scrollView.contentSize = controller.frame.size; [scrollView addSubview:controller]; } ↓MyScrollview .h↓ @interface MyScrollview : UIView<UIScrollViewDelegate>{ } @end ↓MyScrollview .m↓ -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{ ~省略~ SecondViewController *mvc = [[[SecondViewController alloc] initWithNibName:nil bundle:nil] autorelease]; [self.navigationController pushViewController:mvc animated:YES]; }

  • Objective-C グローバル変数 値変更反映

    当方、Objective-Cに関して1年にも満たない経験を持つ初心者です。 初歩的な内容だとは思いますが行き詰まってしまったため質問させて下さい。 複数の.hと.mファイルで定義された複数クラス間で一つの変数を共通で利用し、あるクラスのメソッド内で値を変更した際にそれ以外のクラスですぐに反映出来る様にしたいのですが、どの様に書いても値が反映されず初期値のまま出力されてしまいます。恐らく各クラス内のメソッドが呼ばれる順番に起因すると思うのですが、上手く解決出来ません。 現在書いているコードとして、 -xxxAppDelegate.h (at)interface xxxAppDelegate : NSObject <UIApplicationDelegate> { ... int globalNum; } (at)property(nonatomic, assign)int globalNum; (at)end -xxxAppDelegate.m ... (at)implementation xxxAppDelegate (at)synthesize globalNum; ... (at)end -A.h ... (at)interface AController : UIViewController { xxxAppDelegate *appDelegate; } ... -(void)changeNum; -(IBAction)changeController; (at)end -A.m ... (at)implementation AController ... - init(){ appDelegate = (xxxAppDelegate *)[[UIApplication sharedApplication] delegate]; } ... -(void)changeNum{ //ここでglobalNumの値を変更; appDelegate.globalNum=...; } ... //配置したボタンを押すとA->BにviewControllerを切り替える -(IBAction)changeController{ BController *B = [[BController alloc] initWithNibName:(at)"BController" bundle:nil]; B.modalTransitionStyle = UIModalTransitionStyleCoverVertical; [self presentModalViewController:B animated:YES]; [B release]; } ... (at)end -B.h ... (at)interface BController : UIViewController { xxxAppDelegate *appDelegate; } ... -(void)readNum; (at)end -B.m ... (at)implementation BController ... - init(){ appDelegate = (xxxAppDelegate *)[[UIApplication sharedApplication] delegate]; } ... -(void)readNum{ //globalNumの値を見る; NSLog((at)"%d" , appDelegate.globalNum); } ... (at)end となっています。( (at)=アットマークです。 ) xxxAppDelegateおよびxxxViewControllerよりAControllerを呼び出し、AクラスのchangeNumメソッドでglobalNumの値を変更した後、ボタンを押下してviewControllerをBControllerに切り替え、Bクラス内のreadNumメソッドでglobalNumの値を確認すると、変更が反映されていない事が分かります。 この方法以外にも色々と試してみたのですが、すっきりとしたコードが書けず、解決に至りませんでした。 申し訳ありませんが、皆さんの知恵をお貸し下さい。 よろしくお願いします。

  • iPhoneアプリ とあるプログラムの質問です。

    色々調べたり、書き換えてみたりしたのですが、原因がいまいちよくわかりません。お手上げなので質問させていただきます。 Nabigation-Basedのアプリ製作の中で、テーブル表示から下層画面を選択して、画面遷移をするためのプログラムをRootViewController.mに書いているのですが、シミュレータで実行すると [self.navigationController pushViewController:detailViewController animated:YES]; で、Thread1:Program received signal:"SIGABRT"の表示がでます。(iOS 4.1です) 考えられる原因は何があるでしょうか。ヒントでも構いませんのでよろしくお願い致します。前後の文は下記です。 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { indexPath.section == 0 ; if( indexPath.row == 0 ) { cal_1_UIViewController *detailViewController = [[cal_1_UIViewController alloc] initWithNibName:@"cal_1_UIViewController" bundle:nil]; ☆☆☆[self.navigationController pushViewController:detailViewController animated:YES];☆☆☆→エラーがでます。 [detailViewController release]; }else if( indexPath.row == 1 ) { cal2_UIViewController *detailViewController = [[cal2_UIViewController alloc] initWithNibName:@"cal2_UIViewController" bundle:nil]; [self.navigationController pushViewController:detailViewController animated:YES]; [detailViewController release]; }else if( indexPath.row == 2 ) { cal3_UIViewController *detailViewController = [[cal3_UIViewController alloc] initWithNibName:@"cal3_UIViewController" bundle:nil]; [self.navigationController pushViewController:detailViewController animated:YES]; [detailViewController release]; }

  • cocoa objective-c の return と * の意味がわかりません。

    objective-c の参考書を何冊か購入して 勉強しているのですが、本に載っていないようで ネットでもいくら探しても(探し方が悪いのか)行き当たらないので困ってしまいました。 先に進めなくなってしまいましたので教えていただきたく 投稿しました。 以下のコード(Project Builder起動直後のMyDocument.m)で return self; の return と - (NSString *)windowNibName の * です 使用法を教えていただけたら助かります。 よろしくお願いします。 #import "MyDocument.h" @implementation MyDocument - (id)init { self = [super init]; if (self) { message and return nil. } return self; } - (NSString *)windowNibName { return @"MyDocument"; } - (void)windowControllerDidLoadNib:(NSWindowController *) aController { [super windowControllerDidLoadNib:aController]; } - (NSData *)dataRepresentationOfType:(NSString *)aType { return nil; } - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType { return YES; } @end

  • splitView 詳細画面左上[戻る]の動作

    初めて質問させていいただきます。 iOS開発の初心者です。Xcode4.6.3 storyboard(iPad) にてspritVewControllerを使った場合に、以下の実装をしたいのですが、その方法が分からず困っております。 何卒、よろしくお願いいたします。 【前提】 ・Single View Applicationテンプレート使用して、最初のviewControllerは削除します。 ・splitViewControllerを追加します。 ・splitViewControllerの「Is Initial View Controller」にチェックします。 ・下記サイトを参考にして、Main と Detail 画面は表示されるまでの最低限の実装はしています。(iPad 横、縦切り替えによって、Main と Detail 画面も切り替わる状態です)  http://program.station.ez-net.jp/special/handbook/objective-c/uisplitviewcontroller/implement.asp 【困っている事(やりたい事)】 ・iPad縦向きのときだけ、detail画面の左上ボタン(Mainに戻るボタン)をタップしたとき、自前で実装するactionメソッド(下記参照:backButtonEvent)へ飛ばして、また、このとき、左上ボタンをタップしたときの既存動作(左側からMain画面がスライド表示される)は維持したいのですが、以下の実装をしたところ、自前で追加したactionメソッドには飛びましたが、既存動作(左側からMain画面がスライド表示される)がされなくなりました。 =(EzDetailViewController.h)==★行が追加したところです ★- (IBAction)backButtonEvent:(id)sender; === =(EzDetailViewController.m)==★行が追加したところです - (void)splitViewController:(UISplitViewController*)splitController willHideViewController:(UIViewController*)viewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)popoverController { // 渡された UIBarButtonItem に表示するタイトルを設定します。 barButtonItem.title = @"戻る"; ★ barButtonItem.target = self; ★ barButtonItem.action = @selector(backButtonEvent:);     :     : } ★- (IBAction)backButtonEvent:(id)sender ★{ ★ NSLog(@"Call in backButtonEvent."); ★} === そもそも、既存のbarButtonItemにaction追加したのがいけないのでしょうか。 ※これによって、既存動作処理が行われなくなったと推察していますが。。。 それとも、追加したactionメソッド内で、既存動作処理と同等のことを実装してあげないといけないのでしょうか。(もしそうであれば、この既存動作処理と同等の実装方法をご教授ください) はたまた、他の解決方法等ありましたら、是非、お教えいただきたく、よろしくお願いいたします。

  • iPhoneアプリの開発についてです。

    UINavigationControllerのルートに紐づけられたBookMarkViewControllerというビューがあります。 このBookMarkViewControllerはテーブルビューで、 (1) BookMarkViewController *nextDir = [[BookMarkViewController alloc] init]; [self.navigationController pushViewController:nextDir animated:YES]; 上記のようなコードで、次々と画面遷移していきます。 また、BookMarkViewControllerには、 (2) BookMarkViewController *move = [[BookMarkViewController alloc] init]; move.isMove = YES; UINavigationController *nav = [self.storyboard instantiateViewControllerWithIdentifier:@"BookMarkView"]; [nav setViewControllers:[NSArray arrayWithObjects:move, nil]]; [self presentViewController:nav animated:YES completion:nil]; 上記のような内容のメソッドがあり、次々と画面遷移することのできる新たなUINavigationControllerをモーダル表現で表示します。 画面遷移する前のBookMarkViewControllerでは、上記のコードでうまくモーダルがでるのですが、(1)のメソッドを実行し新たに作り遷移したBookMarkViewControllerではなぜか、 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <BookMarkViewController: 0x11822e070>.' というエラーが吐き出されうまくいきません。 (2)のメソッドで「nav」を生成した直後にnav.viewControllersをNSLogしてみたのですが、nullがかえされてしまいました。(成功した例では<BookMarkViewController ○○○>と、正常に表示されました) 誰かわかる方ご指摘お願いします。

専門家に質問してみよう