【问题标题】:Add a tap gesture recognizer to PDFView in iOS 13在 iOS 13 中向 PDFView 添加轻击手势识别器
【发布时间】:2020-01-29 10:48:58
【问题描述】:

我的代码在 iOS 12 中工作。但升级到 iOS 13 后,它就不能工作了。

let pinPointRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.pinPoint(sender:)))
pinPointRecognizer.numberOfTapsRequired = 1
self.pdfView.addGestureRecognizer(pinPointRecognizer)

我已经尝试添加pinPointRecognizer.numberOfTouchesRequired = 2,它可以触发pinPoint()函数。但我想一键触发pinPoint()

此行为是否会在未来的 iOS 版本中修复?有解决方法吗?

谢谢!

更新:

谢谢大家的回复!很抱歉,我可能没有时间测试你所有的答案。我已更改应用的行为以解决该问题。

我需要在 PDF 文件上添加一个点。我的解决方法是添加一个附加层,在 PDFView 的中心显示一个图钉图标。当用户点击 PDF 视图时,我会在 PDFView 上添加一个图钉图标图像注释。

总之,在我的解决方法中,我仍然使用点击手势识别器。但识别器仅将一个点固定在当前 PDFView 的中心。用户可以放大/缩小并拖动以控制固定点的位置。

【问题讨论】:

    标签: uitapgesturerecognizer ios13 ios-pdfkit


    【解决方案1】:
    let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(toggleTopBottomView(_:)))
    singleTapGesture.numberOfTapsRequired = 1
    singleTapGesture.delegate = self
    self.pdfContainerView.addGestureRecognizer(singleTapGesture)
    
    @objc func toggleTopBottomView(_ sender: UITapGestureRecognizer){
    
    }
    
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    

    【讨论】:

    • 这对我有用,并且与点击链接不冲突。
    【解决方案2】:

    你可以在 Xcode 11、iOS 13 上试试这个

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
    
        tap.numberOfTapsRequired = 1
    
        view.addGestureRecognizer(tap)
    
        view.isUserInteractionEnabled = true
    
    }
    
    @objc func handleTap(_ sender: UITapGestureRecognizer) {
        print("Tapped")
    }
    

    【讨论】:

      【解决方案3】:

      该错误似乎在 iOS 13.2 版本上得到解决。不幸的是,我找不到解决此问题的解决方法。

      【讨论】:

        【解决方案4】:

        实际上我安装了 13.2 Beta 时遇到了同样的问题,但是我找到了一个解决方法。我用 13.1 对其进行了测试,它也可以正常工作。当我确实添加了一个点击手势识别器时,它正在 ios 13 上运行,但是它会吞噬链接上的点击。这是我为解决此问题所做的工作: 我覆盖了 PDFView 子类上的 addGestureRecognizer,然后我旋转并找到一个轻按手势 1 触摸(这是由苹果提供的用于处理链接单击的)并创建我想要显示/隐藏的新轻按手势菜单(或您的自定义操作)。我将它添加到 PDFView 并要求苹果内置的失败(第 15 行)。

        然后我允许 shouldRecognizeSimultaneouslyWithGesture 让两个轻击手势都能调用 correclty。如果您点击一个链接,我的新链接不会被调用,但如果您不点击一个链接,那么它会完美运行并显示/隐藏我的菜单。我希望这对某人有用!

        - (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
        {  
            if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
            {
                UITapGestureRecognizer *tapGest = (UITapGestureRecognizer*)gestureRecognizer;
                if (tapGest.numberOfTapsRequired == 1)
                {
                    if (![tapGest isEqual:singleTapGesture])
                    {
                        if (![self.gestureRecognizers containsObject:singleTapGesture])
                        {
                            singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
                            [singleTapGesture setNumberOfTapsRequired:1];
                            [singleTapGesture setDelegate:self];
                            [singleTapGesture requireGestureRecognizerToFail:tapGest];
                            [self addGestureRecognizer:singleTapGesture];
                        }
                    }
                }
            }
        
            [super addGestureRecognizer:gestureRecognizer];
        }
        
        - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
        {
          return YES;
        }
        

        【讨论】:

        • 你能把它转换成一个 swift 函数吗?
        【解决方案5】:

        不幸的是,我找不到在 iOS 13 之前和之后都以相同方式工作的解决方案,并且这篇文章中的解决方案在激活 PDF 中的链接时会触发点击处理程序。

        这是我想出的解决方案,根据 iOS 版本不同:

        /// Since iOS 13, the way to add a properly functioning tap gesture recognizer on a `PDFView`
        /// significantly changed. This class handles the setup depending on the current iOS version.
        @available(iOS 11.0, *)
        final class PDFTapGestureController: NSObject {
            
            private let tapRecognizer: UITapGestureRecognizer
            
            init(pdfView: PDFView, target: Any?, action: Selector?) {
                assert(pdfView.superview != nil, "The PDFView must be in the view hierarchy")
                
                tapRecognizer = UITapGestureRecognizer(target: target, action: action)
        
                super.init()
                
                if #available(iOS 13.0, *) {
                    // If we add the gesture on the superview on iOS 13, then it will be triggered when
                    // taping a link.
                    // The delegate will be used to make sure that this recognizer has a lower precedence
                    // over the default tap recognizer of the `PDFView`, which is used to handle links.
                    tapRecognizer.delegate = self
                    pdfView.addGestureRecognizer(tapRecognizer)
                    
                } else {
                    // Before iOS 13, the gesture must be on the superview to prevent conflicts.
                    pdfView.superview?.addGestureRecognizer(tapRecognizer)
                }
            }
            
        }
        
        @available(iOS 11.0, *)
        extension PDFTapGestureController: UIGestureRecognizerDelegate {
        
            func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
                return true
            }
            
            func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
                // Make sure we wait for the default PDFView's tap recognizers to fail
                // before triggering our tap handler.
                return (otherGestureRecognizer as? UITapGestureRecognizer)?.numberOfTouchesRequired == tapRecognizer.numberOfTouchesRequired
            }
            
        }
        

        像这样使用它:

        final class PDFViewController: UIViewController {
        
            // Holds a reference to make sure it is not garbage-collected.
            private var tapGestureController: PDFTapGestureController?
        
            open override func viewDidLoad() {
                super.viewDidLoad()
                
                let pdfView = PDFView(frame: view.bounds)
                pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
                view.addSubview(pdfView)
                
                tapGestureController = PDFTapGestureController(pdfView: pdfView, target: self, action: #selector(didTap))
            }
        
            @objc private func didTap(_ gesture: UITapGestureRecognizer) {
                // Necessary to clear the selection with our custom recognizer for iOS 13.
                if pdfView.currentSelection != nil {
                    pdfView.clearSelection()
                } else {
                    // Your tap handler...
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-20
          • 2020-02-21
          • 2019-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多