0

I have a modal presentation for a card that uses a custom presentation controller, which works fine. I now need to use a presentation controller for another popup, but the difficulty is that it needs to be different. I ran into multiple problems trying to overcome this.

First problem: I can obviously not have two same extensions to my view controller, meaning that I can only reference one UIPresentationController File as far as I know. I would, however, ideally need a second UIPresentationController to manage the second Presentation.

Second Problem: Since I could not have a second Extention, I tried using an if statement inside the Extention as such:

extension ThirdViewControllerPassenger: UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
    if something == something {
    PresentationController(presentedViewController: presented, presenting: presenting)
     } else {
     PresentationController2(presentedViewController: presented, presenting: presenting)
     }
}
}

That did not work, I am guessing because I can not change the syntax of the extention. The error was a missing return.

Third problem: My last Idea was to use a user defaults key to save a state and then check the state for each function inside my UIPresentationController. I would for example set defaults.set("showTripOverview", forKey: "presentationStyle") and then split my UIPResentationController Functions into two parts, one if presentationStyle is "ShowTripOverview" and one if its not. The Idea worked out well, the code compiled and it seemed to work. But it wasn't for long when I noticed that all my defaults I set in my main ViewController (that must have run before calling the UIPresentationController!!) were set to nil. So all my if calls were going straight to the else, which was not what I wanted...

Can anyone explain to me how I can fix one of the three issues? I just need to be able to use a second UIPresentationController somehow to tweak the animation ect. for the second presentation. I wouldn't think that it's a strange thing to do since many apps use different ways of presenting things. Could not find anything on the web though...

Jan L
  • 233
  • 1
  • 10
  • 1
    How about not using an extension? You can create different objects to implement the delegate protocol with different implementations of the delegate method and then assign instances of those objects as your presentation delegate as required. You could also just add the two missing `return` statements in the `if` code – Paulw11 Nov 27 '21 at 23:14
  • @Paulw11 I have tried fixing the return statements for the if statement inside my extention, which made the code be able to run, but my conditional was based on a defaults.string for key which did not work because the extention would run before my defaults were set. What do you mean with creating multiple delegates? Can you give me a keyword I can look for to read it up? Can't find anything close to what you said – Jan L Nov 28 '21 at 21:55
  • 1
    You set the `transitioningDelegate` property of a modal presentation to the object that implements the delegate method. It doesn't have to be your view controller. It can be any object that implements the `UIViewControllerTransitioningDelegate` protocol. You don't have to use an extension of a view controller. Having an extension may not be the best approach. If you do want to use a single delegate implementation, don't use user defaults. Simply check the type of `presented` using the `is` operator to know what kind of view controller you are presenting and therefore what to return – Paulw11 Nov 28 '21 at 23:03
  • 1
    so `if presented is FirstUIViewController { return PresentationController(presentedViewController: presented, presenting: presenting) } else { return PresentationController2(presentedViewController: presented, presenting: presenting)}` – Paulw11 Nov 28 '21 at 23:04
  • @Paulw11 ignore the comment I just deleted, it worked! Thanks a lot. I will add your answer to the question in order to answer it for others. I now understand Extentions a bit better. – Jan L Nov 29 '21 at 17:46

1 Answers1

1

For anyone having the same problem and landing here, the following is what worked for me (Thanks to @Paulw11)

It was as simple as adding

extension UIViewController: UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
    
    if presented is someVC {
        return PresentationController(presentedViewController: presented, presenting: presenting)
    } else {
        return PresentationController2(presentedViewController: presented, presenting: presenting)
    }
}

}

This basically fixes the problem I had with my second Idea. Extentions are run too early to be able to use defaults or some other variables. Using if presented is X, X being the ViewController being presented, worked around this issue. Note that since the Extention is still being used, the delegate has to be set to the ViewController the Extention sits on.

Jan L
  • 233
  • 1
  • 10