如何解决如何解决PDFView和SCrollView之间的手势冲突[Swift5,iOS 14]
我正在创建iPad的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)的东西,在这里我可以水平滚动到下一页。
非常感谢您的提前帮助!
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
}
}
解决方法
手势识别器作为处理触摸的链条或流水线工作-一个(G1)失败后,第二个(G2)尝试识别其手势。在这里,您至少有4个识别器-您的2个识别器(left
和right
)和2个scrollView的识别器(pan
和pinch
)。我将提供仅涵盖scrollView的pan
识别器的简短解决方案,如果您还会遇到pinch
的问题-您将需要采用相同的方法。
假设G1是您的left
识别器,而G2
是scrollView的pan
识别器。
为了使G2处理与G1相同的触摸,应告知它们同时识别。
此外,用户在垂直滚动时可能会稍微水平移动手指,因此在这种情况下,您还希望仅在G1放弃滑动但无法识别滑动之后才开始滚动。
为此,您应该将此代码添加到VC中。
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
子类中覆盖其{具有这种逻辑的{1}}方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。