代码之家  ›  专栏  ›  技术社区  ›  James Skidmore

在解除另一个模式视图控制器后立即呈现该控制器

  •  37
  • James Skidmore  · 技术社区  · 14 年前

    我正在关闭一个模态视图控制器,然后立即呈现另一个,但后者从未发生。代码如下:

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

    第一个模态VC滑了下来,但是新的 picker 从不出现。知道怎么回事吗?

    8 回复  |  直到 14 年前
        1
  •  16
  •   Nimrod    14 年前

    像其他动画一样, dismissModalViewControllerAnimated 在视图控制器消失之前不会阻止。相反,它“启动”了视图控制器的解雇。你可能需要在 viewDidDisappear 调用类似于 modalViewControllerDisappeared

        2
  •  52
  •   2snacc    12 年前

    2012年8月更新:

    iOS 5及更高版本引入了更安全的api 之后 情态动词使用完成块设置了进入/离开位置的动画:

    [self presentViewController:myModalVC animated:YES completion:^{}];
    [self dismissViewControllerAnimated:YES completion:^{}];
    

    2012年8月前答案:

    在我看来像是种族状况。。。

    给呈现模式2的方法的调用方加上1+秒的延迟, showModalTwo ,使得模态一被驳回后,模态二每次都出现:

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

    这证实了一种怀疑,即在驳回情态一和提出情态二之间存在某种种族条件。然而,给呼叫者设置延迟是不雅的,并不能保证在其他情况下不会再次出现比赛条件。

    问题

    结果发现 UIViewController modalViewController ,当 presentModalViewController:animated: dismissModalViewControllerAnimated: modalViewController控制器 并按以下方式设置新值。

    1. 呈现模态一。 myViewController.modalViewController
    2. myViewController.modalViewController myViewController.modalViewController 仍然指向模态一
    3. 现在的模态二, myViewController.modalViewController]
    4. 系统回调激发,设置 nil ,这会中断模式2在中设置动画的过程,结果是用户永远看不到它。

    比赛从第2步开始,在第4步开始。

    我的解决方案是对提出模式2的方法设置一个保护条件,以确保 myViewControoler.modalViewController 在尝试呈现模态2之前。

    -(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.
    }
    

    我真的不喜欢这个解决方案的投票方面。@尼姆罗德建议,在这个问题的公认答案中,您可以从 viewDidDisappear: 模态一的方法。我喜欢这种事件驱动方法的声音,但是在我的用例中完成了一个完整的实现之后,我确认当使用内部回调来表示模式2时,竞争条件仍然存在 . 要确定模式2是否会出现,唯一的方法是在父视图控制器内部轮询,直到您确定 self.modalViewController

        3
  •  15
  •   Sid    12 年前
    [self dismissViewControllerAnimated:YES completion:^{
        //Present the new MVC 
    
    }];
    

    注意:从iOS5.0开始提供。

        4
  •  5
  •   Bot    12 年前
    [self dismissModalViewControllerAnimated:NO];
    
     UIImagePickerController *picker = [[UIImagePickerController alloc] init];
     picker.delegate = self;
     picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
     [self presentModalViewController:picker animated:YES];
    
        5
  •  2
  •   Kris Markel    14 年前

    发生的事情是,一旦解除动画完成,视图控制器就会移除它对模式视图控制器的引用,这是在调用此代码之后发生的,因此它认为它没有新的视图控制器来进行模式显示。

    我是如何处理这件事的 didDismissModalVC YES 我打电话之后 dismissModalViewController . 然后在我的 viewDidAppear: 方法,检查ivar的值,然后提出新的模态视图控制器。(记住也要将值设置回 NO 所以我不会被永远解雇模态视图控制器的困扰。)

        6
  •  0
  •   ThanhHH    11 年前

    父视图控制器的定义协议:

    @protocol ParentViewControllerDelegate
    - (void)showModalTwo;
    @end
    

    我在父视图控制器中实现此协议,以显示第二个模式视图控制器并创建委托属性 @property id<ParentViewControllerDelegate> delegate; 在第一个模态视图控制器上。

    显示父视图控制器中的第一个模式视图控制器:

    TheFirstModalViewController *controller = ...
    controller.delegate = self;
    [self presentViewController:controller animated:YES completion:nil];
    ...
    

    打开 viewDidDisappear: 第一个模态视图控制器的方法,只需调用 delegate.showModalTwo:

    希望能帮上忙。

        7
  •  0
  •   Dave    8 年前

    斯威夫特:

    1. 使用dismissViewController关闭第一个显示的视图。
    2. completion block

    var presentingVC_Delegate: mainLists_PopoverDelegation!
    
    @IBAction fund button_Pressed (sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: { finished in
            self.presentingVC_Delegate.presentOtherVC()
            print("DismissVC completion block says hello")
        })
    }
    

    func presentSettingsVC () {
        self.performSegueWithIdentifier("present_OtherVC", sender: nil)
    }
    
        8
  •  0
  •   capikaw    7 年前

    我的方法在iOS 10上运行得很好。我的情况略有不同,但应该适用于大多数情况。我将最初的viewController呈现为一个popover,它要求立即呈现一个模态viewController。

    首先,在初始viewController的 viewDidLoad

       view.isHidden = true
    

    然后,就 viewWillAppear ,显示模式viewController,未设置imated并在完成时取消隐藏视图:

       present(yourModalViewController, animated: false) { [unowned self]
           self.view.isHidden = false
        }
    

    Bool 将出现视图 别把模型呈现出来,但你知道了。