dismissModalViewControllerAnimated nonatomic?

时间:2009-07-21 16:49:30

标签: iphone uiviewcontroller model-view-controller

我似乎有一个奇怪的计时问题。我打开一个uiimagepicker作为模态视图。当用户选择图像或我想拍摄图像时,将其保存到变量中,然后打开电子邮件界面作为模态视图。

我的问题是我在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];

}   
}

我很确定我设计了一些错误的东西,但如果可以,请帮帮我。

5 个答案:

答案 0 :(得分:6)

您可以使用performSelector:withObject:withDelay:等待给定时间传递(创建另一个具有稍后要执行的代码的方法。

然而,这可能会引入许多微妙的时间错误,因此我建议仅将其用于最极端的情况。

我认为您可以使用viewDidAppear:做一些事情,查找您在didFinishPicking…中设置的标记,表示您正在等待imagePicker的动画结束。因为它已经完成了,所以动画应该在那时完成。

答案 1 :(得分: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,然后对dismissModalViewController的调用成功。

答案 2 :(得分:2)

当转换发生时,所有视图都驻留在中间视图(类型UITransitionView)上。因此,只需选择一些您知道它是主窗口的直接子视图的插座并检查是否!([[outlet superview] isKindOfClass:[UIWindow class]])并使用performSelector:withObject:withDelay:延迟执行,传递所有相关信息以调用相同的方法''重新进入并简单地返回。

转换完成后,将不再满足条件,并且可以进行新动画。如果你只需要调用performSelector:withObject:withDelay:一次,这种方法就不会出现时序复杂性。

我最近才使用它并且效果非常好(我恰好有一个主窗口的插座,这使得它更简单):

//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;
    }];
}

答案 3 :(得分:0)

我遇到了类似的问题,并认为这是一个设计问题。我建议不要这样做:

root vc呈现图像vc
root vc解散图像vc
[同时解雇并出现原因问题]
root vc呈现电子邮件vc
root vc驳回了电子邮件vc

你这样做:

root vc呈现图像vc
image vc呈现电子邮件vc
root vc解散vc堆栈

请记住,dismissModalViewController可以解除整个控制器堆栈以进入调用者。请参阅UIViewController的文档。

vc =查看控制器

答案 4 :(得分:0)

我正在使用图像选择器并且dismissModalViewControllerAnimated正在撤消我的一个对象。我发现我必须保存并恢复我的价值。

这对我有用(Group和BigBlockViewController是我的类):

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

我的照片选择器是从flipsideViewController

执行的