在iOS 13中将点击手势识别器添加到PDFView

时间:2019-09-30 06:55:19

标签: uitapgesturerecognizer ios13 ios-pdfkit

我的代码可在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的中心。用户可以放大/缩小并四处拖动以控制固定点的位置。

5 个答案:

答案 0 :(得分:2)

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
    }

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

然后,我允许shouldRecognizeWithSistemtaneouslyWithGesture,它允许两个轻击手势调用正确性。如果您点击一个链接,则不会调用我的新链接,但是如果您未点击一个链接,则该链接会完美工作并显示/隐藏我的菜单。我希望这对某人有用!

- (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;
}

答案 3 :(得分:0)

您可以使用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")
}

答案 4 :(得分:0)

不幸的是,我找不到在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...
        }
    }