Giter Site home page Giter Site logo

interactivemodal's People

Contributors

alberdi avatar chenr2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

interactivemodal's Issues

Transition breaks when quickly gesturing up with a table view

I copied most of your code from the branch that does drag to dismiss with a table view, and found that the transition breaks when you pull the modal view controller down slightly, then push quickly upwards.

`@IBAction func handleGesture(sender: UIPanGestureRecognizer) {
// let shouldDismiss = DragToDismissHelper.sharedInstance.dragToDismiss(sender, searchViewController: self, tableView: googleSearchTableView, view: view)
print("state: (sender.state.rawValue)")
let percentThreshold:CGFloat = 0.3

    // convert y-position to downward pull progress (percentage)
    let translation = sender.translationInView(view)
    // using the helper method
    let progress = progressAlongAxis(translation.y, axisLength: view.bounds.height)

    guard let interactor = interactor,
        let originView = sender.view else { return }

    // Only let the table view dismiss the modal only if we're at the top.
    // If the user is in the middle of the table, let him scroll.
    switch originView {
    case view:
        break
    case googleSearchTableView:
        if googleSearchTableView.contentOffset.y > 0 {
            print("scroll content offset: \(googleSearchTableView.contentOffset.y)")
            return
        }
    default:
        print("about to break")
        break
    }

    print("entering switch")

    switch sender.state {
    case .Began:
        googleSearchTableView.userInteractionEnabled = false
        interactor.hasStarted = true
        dismissViewControllerAnimated(true, completion: nil)
    case .Changed:
        interactor.shouldFinish = progress > percentThreshold
        interactor.updateInteractiveTransition(progress)
    case .Cancelled:
        interactor.hasStarted = false
        interactor.cancelInteractiveTransition()
    case .Ended:

        interactor.hasStarted = false
        interactor.shouldFinish
            ? interactor.finishInteractiveTransition()
            : interactor.cancelInteractiveTransition()
    default:
        break
    }

`
Ignoring the first line of code, which was my attempt to refactor the handleGesture code into a helper function, everything else is the same (googleSearchTableView is equivalent to tableView).

What I believe is happening is that when you add the panGestureRecognizer() to the tableView, it still treats the gesture like a scroll. This means that when the upward gesture occurs, it is actually scrolling the tableView which means that content offset changes, preventing the code from setting the state of the Modal View's interactor appropriately.

I personally fixed the bug by adding a boolean inMiddleOfTransitioning that is initialized as false to the Modal View Controller. Then, I wrap the contentOffset check in an if statement with the parameter !inMiddleOfTransitioning; this is to say that if you're in the middle of the transition to DISREGARD the content offset, allowing for the Interactor state to be set. Then I simply set inMiddleOfTransitioning to true in the .Began case of the sender switch statement.

Sorry if this was a bit convoluted but this has been driving me mad for weeks.

Cheers!

scottpchow23

Transition can break when the presenting and presented view controllers have different status bar styles

I've just spent hours pulling my hair out trying to figure out why my project was exhibiting a strange bug but your project works fine, and I've finally got it! (but not how to fix it, sadly)

If you use view-controller based status bar styles (UIViewControllerBasedStatusBarAppearance in Info.plist), there's a nasty bug that breaks the transition and leaves the app unusable. To replicate, see the following:

Try to drag down on the modal view a tiny bit very quickly (for example, drag down about 50 pixels only just clicking the mouse for a split second)

In the original project, this works as expected - the modal view snaps back to the top, you can continue to do this (or drag further down to dismiss) and the "close" button continues to function.

Now change the status bar style of one of the view controllers so that they're both different - e.g. in ModalViewController.swift:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
}

Run the app and try the same thing a couple of times, and the transition will break: the modal will snap back to the top but will no longer respond to the gesture recognizer, and the "close" button does not work to dismiss the modal view manually. The status bar will be stuck in the state of the presenting view controller.

This only happens when the status bar is a different style between the two view controllers, but I need this in my app, and I'm not sure how to fix it at all. :(

UIPanGestureRecognizer only returns state Began and Cancelled when I put ModalViewController in an UINavigationController

  1. In your example, you're presenting ModalViewController as following flow in storyboard:
    ViewController --(present modally segue)--> ModalViewController
  2. In my case, I need to present ModalViewController in a UINavigationController, so i set up my storyboard as following flow:
    ViewController --(present modally segue)--> UINavigationController --(relationship root view controller)--> ModalViewController

In case (1), panGestureRecognizer will return all available states: Began, Changed, Cancelled, Ended. But in case (2), it will only return Began and Cancelled. Do you have any idea why it happened and how to fix it?

Thank you!

Doesn't work with Swift 3?

Thx for this great tuto, but unfortunately, it doesn't work anymore with Swift 3: the view is directly dismissed when you start to drag.
I reproduce it on my project and I also tried on with this project: same result.
Do you have any idea on how to fix that?
Thanks a lot

Trying this out with UIWebKit Anyideas?

So I wonder how I could get this to work with WKNavigationDelegate, WKUIDelegate? below is my first attempt inside the BrowserViewController which isn't working.

`

let pan = UIPanGestureRecognizer(target: self, action: #selector(handleGesture(sender:)))
    pan.delegate = self
    webView.scrollView.addGestureRecognizer(pan)
}

func progressAlongAxis(pointOnAxis: CGFloat, axisLength: CGFloat) -> CGFloat {
    let movementOnAxis = pointOnAxis / axisLength
    let positiveMovementOnAxis = fmaxf(Float(movementOnAxis), 0.0)
    let positiveMovementOnAxisPercent = fminf(positiveMovementOnAxis, 1.0)
    return CGFloat(positiveMovementOnAxisPercent)
}

@IBAction func handleGesture(sender: UIPanGestureRecognizer) {
    
    let percentThreshold:CGFloat = 0.3
    
    // convert y-position to downward pull progress (percentage)
    let translation = sender.translation(in: view)
    // using the helper method
    let progress = progressAlongAxis(pointOnAxis: translation.y, axisLength: view.bounds.height)
    
    guard let interactor = interactor,
        let originView = sender.view else { return }
    
    print("#\(webView.scrollView.contentOffset.y)")
    // Only let the table view dismiss the modal only if we're at the top.
    // If the user is in the middle of the table, let him scroll.
    switch originView {
    case view:
        break
    case webView:
        if webView.scrollView.contentOffset.y > 0 {
            return
        }
    default:
        break
    }
    
    switch sender.state {
    case .began:
        interactor.hasStarted = true
        dismiss(animated: true, completion: nil)
    case .changed:
        interactor.shouldFinish = progress > percentThreshold
        interactor.update(progress)
    case .cancelled:
        interactor.hasStarted = false
        interactor.cancel()
    case .ended:
        interactor.hasStarted = false
        interactor.shouldFinish
            ? interactor.finish()
            : interactor.cancel()
    default:
        break
    }
}

`

Do I have to use PanGesture? Thinking about putting this logic into the webview contentoffset listner. here:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

Warning after opening modal once

Hi,

I'm following your tutorial about how to implement a custom transition between views and everything is working fine, but after I close the ModalView and then try to open it again, this message is shown on my console:

Warning: Attempt to present <InteractiveModal.ModalViewController: 0x7feffaf0c390> on <InteractiveModal.ViewController: 0x7feffaf0a070> which is already presenting <InteractiveModal.ModalViewController: 0x7feffae0d4b0>

After that, the modal isn't being opened anymore.
Can you please tell me what I should do to solve that?

Thanks,
Renan.

Should I use this demo without prepare(for segue)

I am using this demo to dismiss a view controller and I am presenting it programmatically but when I tried to dismiss it then i will displaying me the blank screen. How Can I resolve it?
Please Help!

custom transition doesn't work when modal with transparent background

I was trying to implement a transparent modal in my project referencing to your tutorial(Thanks for sharing: ] ), as it's doesn't cover full screen, In addition to destinationViewController.transitioningDelegate = self destinationViewController.interactor = interaction, I need to add self.definesPresentationContext = true(<- Important) destinationViewController.modalPresentationStyle = .OverCurrentContext in prepareForSegue for presentingViewController. However, then problem happened that transitioning delegate ( not to say interactor). I tried to search online, but still couldn't get a clue. Do you have any idea what might help?

Many thanks!
Yixiao

Initializer for conditional binding must have optional type, not 'UIView'

Hello! I am trying to simply run this project but getting an error "Initializer for conditional binding must have optional type, not 'UIView'" in DismissAnimator.swift on the line of "let containerView = transitionContext.containerView":

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to), let containerView = transitionContext.containerView else { return }

How do I fix that? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.