在解雇另一个之后立即呈现模态视图控制器

Jam*_*ore 38 iphone objective-c uiimagepickercontroller

我正在解雇模态视图控制器然后立即呈现另一个,但后者永远不会发生.这是代码:

 [self dismissModalViewControllerAnimated:YES];

 UIImagePickerController *picker = [[UIImagePickerController alloc] init];
 picker.delegate = self;
 picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
 [self presentModalViewController:picker animated:YES];

第一个模态VC向下滑动,但新的picker永远不会出现.知道发生了什么事吗?

Pra*_*ogg 52

2012年8月更新:

iOS 5和更高版本已经使用完成块模态动画到/不合适之后引入了更安全的API :

[self presentViewController:myModalVC animated:YES completion:^{}];
[self dismissViewControllerAnimated:YES completion:^{}];
Run Code Online (Sandbox Code Playgroud)

2012年8月之前答案:

当解雇模态一然后快速连续呈现模态二时,我遇到了类似的问题.有时模态二将在模态一被解除后显示,有时模态二不会出现,这让我非常难过.

看起来像我的竞争条件......

在给出模态2的方法的调用者上放置1秒以上的延迟,showModalTwo每次在模态1被解除后出现模态2:

- (void)didDismissModalOne {
    [self performSelector:@selector(showModalTwo:) 
               withObject:someNumber 
               afterDelay:1.0f];
}
Run Code Online (Sandbox Code Playgroud)

这证实了人们怀疑在解雇模式一和提出模式二之间存在某种竞争条件.然而,对呼叫者施加延迟是不优雅的,并且不能保证在其他情况下竞争条件不会再出现.

问题

事实证明,UIViewControllers有一个公共属性,modalViewControllerpresentModalViewController:animated:被调用时被设置并在被调用时被拆除dismissModalViewControllerAnimated:.美中不足的是,它并没有得到同步推倒,所以有可能消除的旧值之间创建一个种族modalViewController和建立以下面的方式一个新值.

  1. 现在的模式一. myViewController.modalViewController现在指向模态一
  2. 解雇模态一.拆除的背景过程myViewController.modalViewController已经开始,但myViewController.modalViewController仍然指向模态的
  3. 现在的模态二,myViewController.modalViewController]现在指向模态二
  4. 系统回调触发,设置myViewController.modalViewControllernil,这会中断模态二动画的过程,结果是用户永远不会看到它.

比赛从第2步开始,并在第4步显示.

解决方案

我的解决办法是把保护条件上所呈现的模态两确保方法myViewControoler.modalViewControllernil试图展示模式前二.

-(void)showModalTwo:(NSNumber *)aParameter {

    if (self.modalViewController) {        
            [self performSelector:@selector(showModalTwo:)
                       withObject:aParameter 
                       afterDelay:0.1f];
            return;
    }
    // You can now present the second modal safely.
}
Run Code Online (Sandbox Code Playgroud)

工作就像一个魅力.更优雅的解决方案可能包括超时.

发布脚本

我真的不喜欢这个解决方案的轮询方面.@Nimrod建议,在这个问题的接受答案中,你可以安全地从viewDidDisappear:模态一的方法开始提出模态二.我喜欢这种事件驱动方法的声音,但在我的用例中完全实现后,我确认在使用内部回调呈现模式二时,竞争条件仍然存在viewDidDisappear:.只有这样,才能绝对保证模式两人将呈现是父视图控制器内部查询,直到你绝对肯定self.modalViewControllernil.然后,只有这样才能"安全"弹出模态二.


Nim*_*rod 16

像其他动画一样,dismissModalViewControllerAnimated在视图控制器消失之前不会阻塞.相反,它"开始"解雇视图控制器.您可能需要使用viewDidDisappear模式控制器1中的回调,该回调调用modalViewControllerDisappeared父视图控制器中的内容.在那种方法中你提出模态控制器2.否则机器人K说什么.


Ilk*_*aci 14

[self dismissViewControllerAnimated:YES completion:^{
    //Present the new MVC 

}];
Run Code Online (Sandbox Code Playgroud)

注意:可用iOS 5.0以上版本.


Sid*_*Sid 5

[self dismissModalViewControllerAnimated:NO];

 UIImagePickerController *picker = [[UIImagePickerController alloc] init];
 picker.delegate = self;
 picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
 [self presentModalViewController:picker animated:YES];
Run Code Online (Sandbox Code Playgroud)

  • 我认为这段代码不会起作用.dismissModalViewControllerAnimated将释放你VC中的所有内容然后你尝试在这个VC上呈现另一个视图控制器 (2认同)