IcaliaLabs / Presentr

Swift wrapper for custom ViewController presentations on iOS
MIT License
3.07k stars 270 forks source link

Issue with modal popup and segued #46

Closed patthehuman closed 7 years ago

patthehuman commented 8 years ago

I've been having an issue with modally Presented view controllers. It looks like if I segue over a Presented view controller with a width and height that is smaller than the view, it stretches out to the full width and height of the screen.

gabrielPeart commented 8 years ago

@patthehuman Thank you! Could you give us a simple prototype that explicitly shows this behaviour? Will save us a lot of time.

danlozano commented 8 years ago

Hey @patthehuman

Mmmm so you are presenting your view controller using a storyboard segue?

Storyboard segues are normal iOS presentations, and those are always full screen.

If you want to make a custom presentation, you must do the presentation in code, using a Presentr object.

customPresentViewController(presenter, viewController: vc, animated: true)
patthehuman commented 8 years ago

Hey, I'll try to get some code together by the weekend.. I'm in PST timezone.

Actually, what I'm doing is presenting a custom presenter using similar code to what you just posted, but I am then calling other segues on top of it.

For example, I use customPresentViewController to show a custom view, and then i segue to different storyboards using interface builder storyboard outlets.

Hope that makes sense... Again, please allow me a few days to get together some code.

I might be able to come up with a fix as well.

danlozano commented 8 years ago

Oooh got it! ... That makes more sense to me now.

I have never tested that use case, yeah let's get some code to test it out and figure out what's happening and fix it 👍

patthehuman commented 8 years ago

Hey guys,

So I use the following code to pop up a "You need to log in" modal... The modal has buttons on it to log in with facebook, email, etc...

`static let loginModal: Presentr = {

        let width = ModalSize.custom(size: 275.0)
        let height = ModalSize.custom(size: 340.0)
        let center = ModalCenterPosition.center
        let customType = PresentationType.custom(width: width, height: height, center: center)

        let customPresenter = Presentr(presentationType: customType) 
        customPresenter.roundCorners = true
        customPresenter.dismissOnSwipe = false
        customPresenter.cornerRadius = 8.0
        customPresenter.transitionType = .coverVertical
        customPresenter.dismissTransitionType = .crossDissolve
        return customPresenter
    }()`

Now, in the storyboard builder, I have other segues coming out of this custom presented modal. One segue goes to the log in with email, one segue opens up the FBSDK login dialog, and another opens up an email log in screen. All of these cause the custom presented dialog to change itsself to max width and height, and then immediately change back.

danlozano commented 8 years ago

OK, got it now. Will try to recreate and see what's going on. If you have any ideas let's discuss it here.

So are these are "push" segues inside a nav controller ? or "presentation" segues ?

What is happening is that somehow the storyboard segues are messing up the transitions/animation/presentation.

I assume if you presented or pushed the other VC's in code (without segues) this probably would not happen, right?

tuancm commented 8 years ago

Hi @danlozano,

I think I have exactly the same issue as @patthehuman . Please see attached sample code. Presentr_Sample.zip

danlozano commented 8 years ago

@tuancm nice, let me check it out!

@patthehuman So are the segues "push" or "present" segues?

danlozano commented 8 years ago

Ok, @tuancm I figured out what the problem was, and I guess this probably applies to @patthehuman as well!

Basically, you can do a regular iOS presentation of a ViewController, which is usually full screen. Or you can do it in code, via Presentr, which let's you handle sizing/presentation/transition/etc... without having to do much code.

When you do a presentation in interface builder using a Segue you are doing a regular iOS presentation.

So basically, in @tuancm code. First, you presented a VC using Presentr, which displayed it as intended, as a popup. But then the second presentation was done using a Segue which does a regular iOS presentation, which is full screen.

To fix this issue, the second presentation must be done in code, using Presentr as well. I just made sure to remove all opacity from the bacgkround of the 2nd presentation since it was going to go on top of the previous presentation's background.

But I really don't recommend doing presentations on top of presentations. If what you want is to show a a set of view controllers (like for a login flow or something like that) you can just present a navigation controller with your view controller, and then just do a PUSH on the remaining view controllers, and it should all work nice, since you're not doing any more "presentations". Makes sense?

Here is your code "fixed".

Presentr_Sample_Fixed.zip

Thanks for the example code @tuancm ! 👍

patthehuman commented 8 years ago

Thanks for the sample code. However, it looks like this is still an issue if you present a facebook login controller on top. In this case, the developer doesn't have access to customize the FB login, so how can we present the facebook controller custom?

tuancm commented 8 years ago

Hi @danlozano ,

I agree with @patthehuman . I can fix the issue within my code. But there's not so much I can do with third party libraries like facebook/google authenticator.

I believe if the issue in my sample code is fixed in a fashion that doesn't me to change the way SignUpViewController is being presented (either using Segue in Storyboard, or using default UIViewController method in code), Presentr will work better with 3rd party frameworks, since many of them use default UIViewController: func present(UIViewController, animated: Bool, completion: () -> Void

Therefore I suggest to re-open this issue.

Best regards, Tuan.

danlozano commented 8 years ago

Hey guys, thanks for the input.

Yeah, we have arrived at the actual problem. Usually presentations in iOS are pretty boring full screen presentations, with some exceptions. That's why Apple introduced the custom view controller presentation API, in which you could customize your own presentations to be any way you like.

But the process to do that was not simple, you had to conform to a couple of delegates, and implement custom logic. And doing that all over the place was a hassle. This framework was built to make those custom view controller presentations simpler by just setting up this Presentr object the way you like, and it handles setting up all the logic.

I think that's this framework's responsibility, making custom view controller presentations easier by wrapping up all the necessary logic.

This problem that you two (and probably more people) are up against I think is out of that scope.

So I honestly think that our own, custom presentations, can be done with Presentr, and be done any way we want them to be. But any third party code that does it's own presentations I think is out our hands.

BUT since this is a real problem that you and maybe other people have I'm willing to re-open this issue, and see if anyone has ideas on why this should be included in Presentr, and maybe more importantly HOW we could fix this problem without doing anything messy.

Thanks for using Presentr, and thanks for taking the tame to try to fix this issue. Let's see what happens.

danlozano commented 8 years ago

Also, what version of the Facebook SDK are you using?

In my experience, the latest version of the Facebook SDK does not do a presentation, it takes you to the actual Facebook app, to approve, then back to your own app. Soooo, I'm confused 🤔

tuancm commented 7 years ago

Hi, Yes I'm using the current Facebook SDK. For most cases when user has facebook app installed on their phone, it will invoke facebook app. Otherwise, an in-app web browser will show up to let user login. The same things happen with Google sign in.

In my case, I'm using following pods to handle facebook/google login:

pod 'Lock'
pod 'Google/SignIn', '~> 1.0'
pod 'Lock-Facebook'
danlozano commented 7 years ago

Oh ok, so this happens when the user does not have Facebook installed, and the SDK modally presents a web view?

Yeah, IDK how we would be able to get in there and change the way they present their own view controllers.

Maybe you should try separating out your own modals/popups/VC's, from the third party FB/Google logins.

I'm still open to other suggestions anyways, so I'll leave this open for discussion. :)