Present and Dismiss Modal View Controller

Present and dismiss modal view controller

First of all, when you put that code in applicationDidFinishLaunching, it might be the case that controllers instantiated from Interface Builder are not yet linked to your application (so "red" and "blue" are still nil).

But to answer your initial question, what you're doing wrong is that you're calling dismissModalViewControllerAnimated: on the wrong controller! It should be like this:

[blue presentModalViewController:red animated:YES];
[red dismissModalViewControllerAnimated:YES];

Usually the "red" controller should decide to dismiss himself at some point (maybe when a "cancel" button is clicked). Then the "red" controller could call the method on self:

[self dismissModalViewControllerAnimated:YES];

If it still doesn't work, it might have something to do with the fact that the controller is presented in an animation fashion, so you might not be allowed to dismiss the controller so soon after presenting it.

Dismiss current modal view controller and then present new modal view controller

I will try to give a more through answer here. When programming in iOS all instances must be created from... other instances. When I say instance I mean an object that has been instantiated (an object that has been created in the computers memory). So, whenever you make a project with XCode, you always need to mark 'the initial view controller'. (See that the bottom right says 'is initial View Controller, ask yourself... why does XCode really need to know that?')This is going to be the first instance that you create. Then it is used to spawn other instances. The reason why Apple chose this architecture is for security reasons (I think...? someone correct me if they have a better answer). You can see a very clear view of all the 'instances' of the views. You click this button while you are running a program in XCode Sample Image. Then you can see the hierarchy of the views. I have made a simple program where clicking a button will load a different view. Where here I have not clicked the button and I have only loaded one view. Before I click the button and add a new view However here I have clicked the button and loaded the next view, Sample Image. At the top they both say UIWindow. That is because... (I hope you can guess this part!) They are both being instantiated from the UIWindow View. Don't believe me? Check this out! Here are the actual view hierarchies.The one where the button has not been pressed and The one where the button has been pressed. So, in the case where you dont get what my point is. You should understand that simply by reading your question it is pretty obvious that you are trying to instantiate your model controller from another one that you are trying to dismiss. So if the model controller has been dismissed how is it supposed to instantiate another model controller? Also keep in mind that it is better to just name your controllers after their purpose like, MenuViewController, or MainController, or VideoController. The word model is usually used in MVC and it should not be used as part of a ViewControllers name. (Hope Im not sounding rude lol, I used to tutor junior high so this is how I teach XD )

Unable to dismiss the modal view controller


let layout = UICollectionViewFlowLayout()
let navController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))
window?.rootViewController = navController

Try this.

Present a view controller, dismiss it and present a different one in Swift

The error occurs because you are trying to present SecondController from FirstController after you have dismissed FirstController. This doesn't work:

self.dismiss(animated: true, completion: {
let vc = SecondController()

// 'self' refers to FirstController, but you have just dismissed
// FirstController! It's no longer in the view hierarchy!
self.present(vc, animated: true, completion: nil)
})

This problem is very similar to a question I answered yesterday.

Modified for your scenario, I would suggest this:

weak var pvc = self.presentingViewController

self.dismiss(animated: true, completion: {
let vc = SecondController()
pvc?.present(vc, animated: true, completion: nil)
})

Swift How to present view in root navigation after dismiss modal

Notice the self in self.present, what you are doing, is basically tell the vc that you are dismissing to present a new vc, thats wrong way to do, the correct way is tell it's PARENT vc to present a new vc, by using delegate/unwind to call the parent vc to present new vc

Disable the interactive dismissal of presented view controller


Option 1:

viewController.isModalInPresentation = true

Disabled interactive dismissal

(Disabled interactive .pageSheet dismissal acts like this.)

  • Since the iOS 13, UIViewController contains a new property called isModalInPresentation which must be set to true to prevent the interactive dismissal.
  • It basically ignores events outside the view controller's bounds. Bear that in mind if you are using not only the automatic style but also presentation styles like .popover etc.
  • This property is false by default.

From the official docs: If true, UIKit ignores events outside the view controller's bounds and prevents the interactive dismissal of the view controller while it is onscreen.



Option 2:

func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
return false
}
  • Since the iOS 13, UIAdaptivePresentationControllerDelegate contains a new method called presentationControllerShouldDismiss.
  • This method is called only if the presented view controller is not dismissed programmatically and its isModalInPresentation property is set to false.

Tip: Don't forget to assign presentationController's delegate. But be aware, it is known that even just accessing the presentationController can cause a memory leak.



Related Topics



Leave a reply



Submit