Attempt to present UIViewController while a presentation is in progress!-Warning

跟風遠走 提交于 2019-12-08 03:10:19

问题


Assume a new iOS project, just with a navigation controller (correctly wired as entry point) and an overridden viewDidAppear() containing the following three lines of code:

            self.presentViewController(UIViewController(), animated: true, completion: nil)
            self.dismissViewControllerAnimated(true, completion: {})
            self.presentViewController(UIViewController(), animated: true, completion: nil)

When executed, that code will raise a warning "Attempt to present UIViewController while a presentation is in progress!" when attempting to present the second controller.

Question: What exactly am I missing in order to dismiss the controller correctly before calling another controller?


回答1:


You'll need to add some sort of delay on that initial presentViewController call as illustrated below:

override func viewDidAppear(animated: Bool) {
    presentViewController(UIViewController(), animated: true) { () -> Void in
        self.delay(0.1, closure: { () -> () in
            self.dismissViewControllerAnimated(true, completion: nil)
        })
    }
}


func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

It seems the completion block is called before the animation is truly complete.




回答2:


Assuming you want the main controller to appear, present a controller, dismiss the controller, present again and dismiss then you need to chain the actions so they happen in order.

To prevent it spinning forever, you also need to only run the code when the main controller appears for the first time.

I'm no swift coder, but something like the following should work. There is a check to make sure the controller is being presented or being pushed on and then it runs the sequence using each operations completion to start the next. This guard should make sure that following each dismiss when viewDidAppear gets called that it does not do anything on those occasions.

var firstTime = true;

func presentThenDismiss(finalCompletion: (() -> Void)?)
{
    presentViewController(UIViewController(), animated: true, completion : { [weak self] Void in
        // On completion of the present, we dismiss it
        dispatch_async(dispatch_get_main_queue(), {
            self?.dismissViewControllerAnimated(true, completion: { Void in
                // On completion of the dismiss, we present another
                finalCompletion!()
            })
        })
    })
}

override func viewDidLoad() {
    super.viewDidLoad()


    // We only run the modal presentation code when being presented or
    // being pushed on, NOT when exposed by a model dismiss or pop
    //
    if (firstTime){
        firstTime = false;

        self.presentThenDismiss { () -> Void in
            self.presentThenDismiss { () -> Void in
            }
        }
    }
}


来源:https://stackoverflow.com/questions/32460224/attempt-to-present-uiviewcontroller-while-a-presentation-is-in-progress-warning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!