Screen edge gesture is not recognized in PDFView (UIViewer) [Swift, iOS 15, PDFKit] - swift

I am displaying a PDF file and would like to add a screen edge gesture to move pages around.
The following code works fine when entire the content of a PDF is displayed on the screen. However, when the PDF was zoomed, the screen edge gesture cannot even activate.
override func viewDidLoad(){
super.viewDidLoad()
//set up gesture to swipe from the edge
let leftScreenEdgeRecognizer = UIScreenEdgePanGestureRecognizer (
target: self, action: #selector(TextDocumentViewController.leftEdgePanGestureHandler(_ : )))
leftScreenEdgeRecognizer.edges = UIRectEdge.left
let rightScreenEdgeRecognizer = UIScreenEdgePanGestureRecognizer (
target: self, action: #selector(TextDocumentViewController.rightEdgePanGestureHandler(_ : )))
rightScreenEdgeRecognizer.edges = UIRectEdge.right
//register the gesture
pdfView.addGestureRecognizer(leftScreenEdgeRecognizer)
pdfView.addGestureRecognizer(rightScreenEdgeRecognizer)
}
//gesture functions here
#objc func leftEdgePanGestureHandler(_ sender: UIScreenEdgePanGestureRecognizer){
if(sender.state == UIGestureRecognizer.State.ended){
print ("Left Edge")
pdfView.goToPreviousPage(sender)
}
}
#objc func rightEdgePanGestureHandler(_ sender: UIScreenEdgePanGestureRecognizer){
if(sender.state == UIGestureRecognizer.State.ended){
print ("right Edge")
pdfView.goToNextPage(sender)
}
}
I tired to add a code like,
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
However, this is not working at all.

I was able to solve this problem thanks to the answer provided for my old question. I have totally forgotten about the post. After learning more about multiple gesture detections through try and error, I realized that I can do as follows to solve this posted question:
Enables the multiple gesture activation:
class ViewController: UIViewController, UIGestureRecognizerDelegate, UIDocumentPickerDelegate, PDFViewDelegate {
// ... other things
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer:
UIGestureRecognizer) -> Bool {
return true
}
}
Make sure to appropriately set delegate.
override func viewDidLoad(){
super.viewDidLoad()
//set gesture
leftScreenEdgeRecognizer.delegate = self
rightScreenEdgeRecognizer.delegate = self
}

Related

How to disable tap gesture recognizer UIButton for dismisskeyboard?

I have this code:
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap = UITapGestureRecognizer(target: self, action: #selector(self.dissmissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
// Don't handle button taps
return !(touch.view is UIButton)
}
This is a global function!
When I press the login button the keyboard disappears and then I must to press it again to login. Is there a way to avoid this?
I want that when I press login button keyboard not disappear but when I press outside button keybord disappear
What you are missing is the delegate.
tap.delegate = self
Since you haven't add the delegate, your
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
method will not execute.
Have a breakpoint there and see that it is execute or not. I don't think so. By adding the delegate that I mentioned earlier will do the trick.
The code will be look like below.
let tap = UITapGestureRecognizer(target: self, action: #selector(self.dissmissKeyboard))
tap.delegate = self
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
In the class you should implement the delegate class like below.
class ViewController: UIViewController, UIGestureRecognizerDelegate {

How to disable swipe back specifically on only one view controller

I know there have been similar questions asked, but none of them have worked for me.
I have this code to enable swiping back in my project
class InteractivePopRecognizer: NSObject {
// MARK: - Properties
fileprivate weak var navigationController: UINavigationController?
// MARK: - Init
init(controller: UINavigationController) {
self.navigationController = controller
super.init()
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
}
extension InteractivePopRecognizer: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return (navigationController?.viewControllers.count ?? 0) > 1
}
// This is necessary because without it, subviews of your top controller can cancel out your gesture recognizer on the edge.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
I have this VC stack
HomescreenVC -> Login/SignupVC -> UserProfileVC
I do not want them to be able to swipe back from the UserProfileVC.
A better approach is to clear them from the stack when you show UserProfileVC
let profile = self.storyboard?.instantiateViewController(withIdentifier: "profileID") as! UserProfileVC
self.navigationController?.viewControllers = [profile]
Edit: Do this inside profileVC
self.navigationController?.viewControllers = [self]
//
self.view.alpha = 0
UIView.animate(withDuration: 0.5) {
self.view.alpha = 1
}
I think you can remove gesture Recognizer from there too why you are not trying that.
Try something like this:-
view.gestureRecognizers?.removeAll()

Two UIGestureRecognizer on one view?

I am using spriteKit. I don't kwon whether this is important. I've initialized two UIGestureRecognizer to my view in didMove(toView):
let longPress = UILongPressGestureRecognizer()
longPress.minimumPressDuration = CFTimeInterval(0.0)
longPress.addTarget(self, action: #selector(self.longPressGesture(longpressGest:)))
self.view?.addGestureRecognizer(longPress)
let swipeUp = UISwipeGestureRecognizer()
swipeUp.direction = UISwipeGestureRecognizerDirection.up
swipeUp.addTarget(self, action: #selector(self.swipeUpGesture(swipe:)))
self.view?.addGestureRecognizer(swipeUp)
My Problem is that only the first gestureRecognizer is called (longpressGest). When I delete the first GestureRecognizer, the swipeGestureRecognizer does work. How can I solve this?
You need to make your Game Scene view the delegate of your gesture recognizer. You will also need implement its method shouldRecognizeSimultaneouslyWith as mentioned by xmasRights:
So in your Game scene declaration just add UIGestureRecognizerDelegate:
class GameScene: SKScene, SKPhysicsContactDelegate, UIGestureRecognizerDelegate {
And in your didMove(to view: SKView) method make set its delegate:
let longPress = UILongPressGestureRecognizer()
longPress.delegate = self
longPress.minimumPressDuration = 0
longPress.addTarget(self, action: #selector(longPressGesture))
view.addGestureRecognizer(longPress)
let swipeUp = UISwipeGestureRecognizer()
swipeUp.delegate = self
swipeUp.direction = .up
swipeUp.addTarget(self, action: #selector(swipeUpGesture))
view.addGestureRecognizer(swipeUp)
Also In Swift 4 you will need to add #objc to your methods
#objc func longPressGesture(_ longPress: UILongPressGestureRecognizer) {
print("longPressGesture")
}
#objc func swipeUpGesture(_ swipeUp: UISwipeGestureRecognizer) {
print("swipeUpGesture")
}
Don't forget also to add the method shouldRecognizeSimultaneouslyWith as already mentioned by xmasRights:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("shouldRecognizeSimultaneouslyWith")
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
{
return true
}
https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/allowing_the_simultaneous_recognition_of_multiple_gestures
You could also use the same gesture recognizer and differ between the two gesture inside of this function

numeric keyboard resigns to normal key board in swift

I have a normal set up for a textfield with numberpad and the dismiss keyboard and resignFirstResponder actions in place, but when I tap on the background the numeric keyboard changes to the normal keyboard and then when I tap the background again the keyboard dismisses - STRANGE! How can I dismiss the numeric keyboard with one tap to the background?
self.textField.delegate = self
textField.keyboardType = UIKeyboardType.DecimalPad
#IBAction func tapBackground(sender: AnyObject) {
view.endEditing(true)
}
#IBAction func viewTapped(sender: AnyObject) {
textField.resignFirstResponder()
}
Try following this may help you :)
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: "handleTapGesture:")
tap.delegate = self
self.view.addGestureRecognizer(tap)
}
// MARK: - UITapGestureRecognizer
func handleTapGesture(gesture : UITapGestureRecognizer) {
self.view.endEditing(true)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool
{
return true
}

ios8 gesture recognizer does not work on WKWebView with swift

i"m trying to implement a long press gesture recognizer on a WKWebView as follows:
var webView: WKWebView?
let longPressRecognizer = UILongPressGestureRecognizer()
override func loadView() {
super.loadView()
var webViewConfig: WKWebViewConfiguration = WKWebViewConfiguration()
webViewConfig.allowsInlineMediaPlayback = true
webViewConfig.mediaPlaybackRequiresUserAction = false
self.webView = WKWebView(frame: self.view.frame, configuration: webViewConfig)
self.view = self.webView!
//hook the long press event
longPressRecognizer.addTarget(self, action: "onLongPress:")
self.webView!.scrollView.addGestureRecognizer(longPressRecognizer)
}
func onLongPress(gestureRecognizer:UIGestureRecognizer){
NSLog("long press detected")
}
i don't get an error but i cant seem to make it trigger the onLongPress function.
You didn't set the delegate of the gesture recognizer.
//hook the long press event
longPressRecognizer.delegate = self
longPressRecognizer.addTarget(self, action: "onLongPress:")
self.webView!.scrollView.addGestureRecognizer(longPressRecognizer)
In case that it still doesn't work, this may probably due to WKWebView already has its own gesture recognizers. Then add the following method to your class:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
And in your event method check for the gesture began:
func onLongPress(gestureRecognizer:UIGestureRecognizer){
if gestureRecognizer.state == UIGestureRecognizerState.Began {
NSLog("long press detected")
}
}