thorntechpublic / interactivemodal Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
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
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. :(
ViewController --(present modally segue)--> ModalViewController
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!
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
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?) {
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.
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!
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
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!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.