2009-07-21 5 views
2

私は奇妙なタイミングの問題を抱えているようです。私はモーダルビューとしてuiimagepickerを開きます。ユーザーが画像を選択したとき、または画像を取得したいときは変数に保存し、電子メールインターフェイスをモーダルビューとして開きます。dismissModalViewControllerAnimated非アトミック?

私の問題は、imagepickerでdismissModalViewControllerを呼び出してから、自分の電子メールインターフェイスにpresentmodalviewcontrollerを呼び出していますが、imagepickerが電子メールビューを表示するために外れていないことです。そのコード行が完了するのを待つ方法はありますか?

(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 
    if([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:@"public.image"]){ 
    [self dismissModalViewControllerAnimated:YES]; 
    imageFromCamera = [[UIImageView alloc] initWithImage:[info objectForKey:UIImagePickerControllerOriginalImage]]; 

    MFMailComposeViewController *mailView = [[MFMailComposeViewController alloc] init]; 
    mailView.mailComposeDelegate = self; 
    [self presentModalViewController:mailView animated:YES]; 
    [mailView release]; 

} 
} 

私はかなり間違った設計をしていますが、できれば助けてくれます。

あなたが

しかし、これは微妙なタイミングのバグの多くを導入することができます。後で実行するコードを持つ別のメソッドを作成(渡すために与えられた時間を待つperformSelector:withObject:withDelay:を使用することができますので、私はそれを使用することをお勧めしたい

答えて

6

viewDidAppear:と入力すると、didFinishPicking…に設定したフラグを探して、imagePickerのアニメーションが終了するのを待っていることを示していることが考えられます。それまでにアニメーションを行う必要があります。

+0

おかげで、から行われます。 – Alfonsol

2

私は遭遇しましたdismissModalViewControllerと同様の問題を引き起こし、それは私をナットにしています。私がそれに対処することができた唯一の方法は、上記のようなことをすることです。私はこの解決策が嫌いですが、私はそれを避ける方法を見つけ出すことができませんでした。

if ([self retainCount] == 1) 
    [self dismissModalViewControllerAnimated:YES];      
else { 
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES]; 
} 

- (void)onTimer:(NSTimer*)theTimer { 
    [self dismissModalViewControllerAnimated:YES]; 
    [theTimer invalidate]; 
} 

私が気づいた問題は、いくつかのオブジェクトがモーダルビューコントローラを保持しているときのタイミング問題です。また、retainCountが2のときにdismissModalViewControllerを呼び出すと、呼び出しが失敗するだけです。何も起こりません。しかし、1秒待つと、保持カウントは常に1に減少し、dismissModalViewControllerの呼び出しは成功します。

+0

これは私のために働いた。ありがとう! –

2

遷移が起こっている間に、すべてのビューは中間のビュー(タイプUITransitionView)にあります。したがって、メインウィンドウの直接のサブビューであることを知っているコンセントをいくつか選択して、!([[outlet superview] isKindOfClass:[UIWindow class]])をチェックし、実行をperformSelector:withObject:withDelay:で遅らせるかどうかをチェックし、関連するすべての情報を渡して、同じメソッドを呼び出して戻します。

移行が完了すると、条件はもう満たされず、新しいアニメーションが発生する可能性があります。この方法では、performSelector:withObject:withDelay:を1回だけ呼び出すと発生する可能性のあるタイミングの複雑さに敏感ではありません。

私は最近、これを使用し、それは(私はこれがさらに簡単になり、メインウィンドウへの出口を持つことが起こった)非常によく動作します:

//Called after [initialRootViewController dismissModalViewControllerAnimated:YES] 
- (void)showTable { 
    if([initialRootViewController.view superview] != window) { 
     //View is still animating 
     [self performSelector:@selector(showTable) withObject:nil afterDelay:0.1]; 
     return; 
    } 
    self.nibContents = [[NSBundle mainBundle] loadNibNamed:@"MainView" owner:self options:nil]; 
    [UIView transitionFromView:initialRootViewController.view toView:rootViewController.view duration:0.3 options:UIViewAnimationOptionTransitionCurlUp|UIViewAnimationOptionBeginFromCurrentState completion:^(BOOL finished){ 
     self.initialRootViewController = nil; 
    }]; 
} 
+0

この方法は私にとって素晴らしい仕事でした。テストを変更して、initialRootViewController.view superview!= NULLをチェックするようにしました。ビューのアニメーション化が終了するとNULLになります。 –

0

私は同様の問題を抱え、それがあると信じていますデザインの問題。私はやってするのではなく、お勧めします:

ルートVCは、画像VC
ルートVCは
[ここ同時閉じ、現在、原因の問題]画像VCを閉じる提示
ルートVCは電子メールVC
ルートVCは電子メールのVCを閉じる提示します

あなたは実行します。

ルートVCは、画像VC
画像VCの前を提示しますsents email vc
root vcはvcスタックを破棄します。

dismissModalViewControllerは、コントローラスタック全体を閉じて、呼び出し元に到達することができます。 UIViewControllerのドキュメントを参照してください。

VC =ビューコントローラ

0

私はイメージピッカーを使用していますし、dismissModalViewControllerAnimatedは私のオブジェクトの1つを元に戻しています。私は自分の価値を保存して復元しなければならないことがわかった。

これは(グループとBigBlockViewControllerは私のクラスである)私の仕事です:

Group *workAround = bigBlockViewController.selectedGroup; 
[picker dismissModalViewControllerAnimated:YES]; 
bigBlockViewController.selectedGroup = workaround; 

マイフォトピッカーがとても役に立ちましたflipsideViewController

関連する問題