首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解决PDFView和SCrollView [Swift5,iOS 14]之间的手势冲突

如何解决PDFView和SCrollView [Swift5,iOS 14]之间的手势冲突
EN

Stack Overflow用户
提问于 2020-09-25 22:58:50
回答 1查看 912关注 0票数 1

我正在为iPads创建一个PDF查看器,用户可以通过滚动水平来读取PDF。

我创建了下面的代码来实现带有手势的页面更改(同时咨询How to create a single page vertical scrolling PDFView in Swift和其他地方)的单一页面视图。

虽然这种方法在大多数情况下都能很好地工作,但我意识到当PDF文件被放大时,没有检测到(或调用)手势。因此,我不能通过滑动屏幕进入下一页。使用我创建的extension PDFView {}函数,我发现禁用subview中的用户交互使我能够检测到滑动手势。但是,现在我不能在PDFView中滚动页面。如果你能帮我解决这个问题,我会很感激的。

我想要实现的是类似于‎PDF Expert (https://apps.apple.com/us/app/pdf-expert-pdf-reader-editor/id743974925)的东西,在这里我可以水平滚动到下一页。

非常感谢您的帮助,提前!

代码语言:javascript
复制
import UIKit
import PDFKit

//PDF Zoom scale
var scaleOfPdf: CGFloat = 4

extension PDFView {
    func disableBouncing(){
        for subview in subviews{
            if let scrollView = subview as? UIScrollView{
                scrollView.bounces = false
                return
            }
}

class ViewController: UIViewController, UIGestureRecognizerDelegate,  UIDocumentPickerDelegate {

    @IBOutlet weak var pdfView: PDFView!
    
    override func viewDidLoad(){
        super.viewDidLoad()


            pdfView.autoresizesSubviews = true
            pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleTopMargin, .flexibleLeftMargin]
            
            pdfView.displayDirection = .horizontal
            pdfView.displayMode = .singlePage
            pdfView.autoScales = true
            // setting a color for background
            pdfView.backgroundColor = .black
            pdfView.document = pdfDocument
            //            pdfView.usePageViewController(true, withViewOptions: [UIPageViewController.OptionsKey.interPageSpacing: 20])
            pdfView.maxScaleFactor = 4.0
            pdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit
            
            pdfView.disableBouncing()  


       //setting swipe gesture
        let leftSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(respondLeftSwipeGesture(_:)))
        leftSwipeGesture.direction = [UISwipeGestureRecognizer.Direction.left]
        pdfView.addGestureRecognizer(leftSwipeGesture)
        
        let rightSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(respondRightSwipeGesture(_:)))
        rightSwipeGesture.direction = [UISwipeGestureRecognizer.Direction.right]
        pdfView.addGestureRecognizer(rightSwipeGesture)

    }
    
        
    //setting swipe-gesture
    @objc func respondLeftSwipeGesture(_ sender: UISwipeGestureRecognizer) {
        print("left swipe was detected")
        if pdfView.document == nil { return }
        scaleOfPdf = pdfView.scaleFactor
        pdfView.goToNextPage(self)
        pdfView.scaleFactor = scaleOfPdf
    }
    
    @objc func respondRightSwipeGesture(_ sender: UISwipeGestureRecognizer) {
        print("right swipe was detected")
        if pdfView.document == nil { return }
        scaleOfPdf = pdfView.scaleFactor
        pdfView.goToPreviousPage(self)
        pdfView.scaleFactor = scaleOfPdf
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-26 04:49:17

手势识别器是一个链式或流水线,处理触摸-在一个(G1)失败后,第二个(G2)试图识别它的手势。这里至少有4个识别器--你的2个(leftright)和2个滚动视图(panpinch)。我将给出一个简单的解决方案,它只涵盖滚动视图的pan识别器,如果您也会看到pinch的问题--您将需要遵循相同的方法。

假设G1是您的left识别器,G2是滚动视图的pan识别器。为了使G2过程与G1过程相同,应该要求它们同时识别。

此外,用户在垂直滚动时可能会水平移动手指,因此在这种情况下,您还希望只有在G1放弃滑动而无法识别时才开始滚动。

为了实现这一点,您应该将此代码添加到您的VC中。

代码语言:javascript
复制
override func viewDidLoad(){
    super.viewDidLoad()
    
    ...
    
    leftSwipeGesture.delegate = self
    leftSwipeGesture.cancelsTouchesInView = false
    rightSwipeGesture.delegate = self
    rightSwipeGesture.cancelsTouchesInView = false
}

optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
                                shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return gestureRecognizer == leftSwipeGesture
        || gestureRecognizer == rightSwipeGesture
        || otherGestureRecognizer == leftSwipeGesture
        || otherGestureRecognizer == rightSwipeGesture
}

optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
                                shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    guard let _ = gestureRecognizer as? UIPanGestureRecognizer else { return false }
    return otherGestureRecognizer == leftSwipeGesture
        || otherGestureRecognizer == rightSwipeGesture
}

optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
                                shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    guard let _ = otherGestureRecognizer as? UIPanGestureRecognizer else { return false }
    return gestureRecognizer == leftSwipeGesture
        || gestureRecognizer == rightSwipeGesture
}

如果我添加的UIGestureRecognizerDelegate方法没有被调用,您将需要创建一个子类PDFView,使left/rightSwipeGesture.delegate = pdfView并在您的PDFView子类中使用这个逻辑覆盖它的UIGestureRecognizerDelegate方法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64072267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档