2013/11/05

【Objective-C/iOS】Segueで子ビューに移ったらエラーが出る

後藤です。ごぶさたです。

恥ずかしながらdelegateについて何となくしかわからずにいたので、このままではいけないと思い、すごく初歩的なとこからdelegateの練習をしておりました。その中でエラーが出て、???となったところについて、書きます。ちなみにエラー内容はdelegateとはあまり関係ないです。

【前提】
・Xcode5/Mac OSX 10.8
・ストーリーボードを使います



上記のような、とても簡単な構成になっています。動作は下記のような感じです。
1. ナビゲーションバーがついた親ビュー(黄色)の真ん中にある「Button」ボタンを押す
2. pushセグエで子ビュー(ピンク)に移る
3. 子ビューの真ん中にある「Touch me!!」ボタンを押すと、親ビューのViewControllerのメソッドに書いたアラートが出る

が、親ビューの「Button」を押すと下記のようなエラーが出ます。
nested push animation can result in corrupted navigation bar
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

ちなみにナビゲーションバーの戻るボタンのところを見てみても、前のビューがsubViewとなっていてどう見てもおかしいです(下図左)。ちなみにここでpushから戻ると、得体のしれない黒いSubViewが間にあり、そこから親ビューに戻る風になってしまっています(下図右)。この中間にあった黒いビューのナビゲーションバーの戻るボタンを押すと、いろいろエラーが出て落ちてしまいます。



ちなみに一応セグエをmodalにして試してみたりもしましたが、下記のような違うエラーが出るだけでやっぱり落ちてしまいます。(英語の意味は…読んでいません。)
Warning: Attempt to present  on  while a presentation is in progress!

これなんですが、エラーの原因はとても初歩的なものでした。
親ビューの方のボタンから右クリックで紐をのばして、そのまま子ビューに移るようなセグエを作っていたのに、そのボタンのIBActionのメソッドの中でもセグエで遷移するperformSegueWithIdentifierを書いてしまっていたので、二重でセグエを通ることになっていたみたいです。
- (IBAction)touchButton:(id)sender {
    [self performSegueWithIdentifier:@"gotoSubview" sender:self];
}
このperformSegueWithIdentifierのメソッドをそのままコメントアウトするだけでちゃんと動くようになりました。 近日、TableViewCellのセルをタッチしたらセグエで遷移する〜とかいうのばかりを書いていて、ボタン押したらそのままセグエが発動するようなものを書いたのが久しぶりだったので勘違いしていたみたいです。が、ボタンを押して画面遷移するときってIBActionのメソッドの中って何を書いていたっけ??空白?はかっこ悪いので違う気がするんですが、思い出せない…。 追記: ふつうにボタンとビューをセグエでつないだときは別にメソッドとか何も追加されなかった! ちなみに、今回のコードはこんなかんじでした。 ■ ViewController.h(親ビューのほう)
#import 
#import "subViewController.h"

@interface ViewController : UIViewController

- (IBAction)touchButton:(id)sender;

@end
■ ViewController.m
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void) helloDelegate
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
                                                    message:@"\Hello, delegate!/"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}

- (IBAction)touchButton:(id)sender {
//    [self performSegueWithIdentifier:@"gotoSubview" sender:self];
}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    subViewController *svc = (subViewController *)[segue destinationViewController];
    svc.delegate = self;
}

@end
■ subViewController.h(子ビューのほう)
#import 

@protocol subViewControllerDelegate;

@interface subViewController : UIViewController

@property (nonatomic, assign) id  delegate;
- (IBAction)touchSubViewButton:(id)sender;
@end

@protocol subViewControllerDelegate 
- (void) helloDelegate;
@end
■ subViewController.h
#import "subViewController.h"

@interface subViewController ()
@end

@implementation subViewController
@synthesize delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (IBAction)touchSubViewButton:(id)sender {
    [self.delegate helloDelegate];
}

@end
もっと良い書き方などありましたらぜひご指摘くださいませ。 後藤でした。

0 件のコメント :

コメントを投稿