检测PDFView是否滚动

时间:2018-01-10 10:07:24

标签: ios cocoa-touch

iOS上的PDFKit是否公开了PDFView的底层UIScrollView,还是有其他方法直接检测用户是否滚动了PDFView?

我的用例是在滚动文档时隐藏导航栏以便解决方法我已经将自己的平移手势识别器添加到PDFView的父级并且我在gestureRecognizerShouldBegin中隐藏并始终返回false但我希望有一些东西更像是我在文档中遗漏的UIScrollViewDelegate。

3 个答案:

答案 0 :(得分:1)

试试这个,

NotificationCenter.default.addObserver(self, selector: #selector(handlePageChange(notification:)), name: Notification.Name.PDFViewPageChanged, object: nil)

@objc private func handlePageChange(notification: Notification)
{
    print("Page changed")
}

答案 1 :(得分:0)

我这样做是为了检测pdfView上的缩放和平移,以将这些手势复制到第二个pdfView中,并且在这里工作得很好。 我在这里找到的PanDirectionGestureRecognizer获得了一些检测垂直和水平平移的帮助:stackoverflow.com/a/55635482/558112

class Document: UIViewController, UIScrollViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Subscribe to notifications.
        NotificationCenter.default.addObserver(self, selector: #selector(onPageZoomAndPan), name: .PDFViewScaleChanged, object: pdfView

        // get the scrollView in pdfView and attach gesture recognizers

        outerLoop: for subView in pdfView.subviews {
            for view in subView.subviews {
                if let scrollView = view as? UIScrollView {
                    let xScrollViewPanGesture = PanDirectionGestureRecognizer(direction: .horizontal, target: self, action: #selector(onPageZoomAndPan))
                    xScrollViewPanGesture.delegate = self
                    scrollView.addGestureRecognizer(xScrollViewPanGesture)

                    let yScrollViewPanGesture = PanDirectionGestureRecognizer(direction: .vertical, target: self, action: #selector(onPageZoomAndPan))
                    yScrollViewPanGesture.delegate = self
                    scrollView.addGestureRecognizer(yScrollViewPanGesture)

                    break outerLoop
                }
            }
        }
    }

    // MARK: - UIScrollViewDelegate

    @objc private func onPageZoomAndPan() {
        let rect = pdfView.convert(pdfView.bounds, to: pdfView.currentPage!)
        pdfViewSecondScreen.scaleFactor = pdfView.scaleFactor
        pdfViewSecondScreen.go(to: rect, on: pdfView.currentPage!)
    }
}



enum PanDirection {
    case vertical
    case horizontal
}


// UIKit.UIGestureRecognizerSubclass

import UIKit.UIGestureRecognizerSubclass

class PanDirectionGestureRecognizer: UIPanGestureRecognizer {

    let direction : PanDirection

    init(direction: PanDirection, target: AnyObject, action: Selector) {
        self.direction = direction
        super.init(target: target, action: action)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)

        if state == .began {
            let vel = velocity(in: self.view!)

            switch direction {
            case .horizontal where abs(vel.y) > abs(vel.x):
                state = .cancelled
            case .vertical where abs(vel.x) > abs(vel.y):
                state = .cancelled
            default:
                break
            }
        }
    }
} 

答案 2 :(得分:0)

iOS上的PDFKit是否公开PDFView的基础UIScrollView

否,但希望Apple将来会添加它。我记得UIWebView最初没有它,后来又添加了它。

或者还有其他方法可以直接检测到用户已滚动PDFView

否,PDFViewDelegate提供的通知似乎都没有解决这个问题。

我正在从UIWebView迁移到PDFView,并使用scrollViewDidScroll来处理很多东西,所以我不想仅仅依靠添加摇摄手势识别器。根据@Matthijs的答案,我在PDFView中找到UIScrollView,将我的类作为其委托,然后将所有事件传递回滚动视图(在我的类成为委托之前是其自己的委托),以便它可以响应也一样使用UIWebView,最后一步不是必需的,但是使用PDFView,没有它,缩放和其他功能可能无法使用。

我要重写所有记录在案的委托方法,以减少如果Apple更改PDFView的内部功能,则该方法会中断的机会。但是,我必须在每种方法中检查respondsToSelector,因为原始的滚动视图委托当前并未实现所有它们。

- (void)viewDidLoad {
    // create the PDFView and find its inner scrollView
    self.pdfView = [[PDFView alloc] init];
    for (UIView *subview in self.pdfView.subviews) {
        if ([subview isKindOfClass:[UIScrollView class]]) {
            self.scrollView = (UIScrollView *)subview;
        } else {
            for (UIView *subsubview in subview.subviews) {
                if ([subsubview isKindOfClass:[UIScrollView class]]) {
                    self.scrollView = (UIScrollView *)subsubview;
                }
            }
        }
    }
}

- (void)loadPDFDocument:(NSString *)URL {
    // load a document, then become the delegate for the scrollView (we have to do that after loading the document)
    PDFDocument *document = [[PDFDocument alloc] initWithURL:URL];
    self.pdfView.document = document;
    self.scrollView.delegate = self;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // *** respond to scroll events here ***

    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
        [scrollViewDelegate scrollViewDidScroll:scrollView];
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewWillBeginDragging:)]) {
        [scrollViewDelegate scrollViewWillBeginDragging:scrollView];
    }
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:)]) {
        [scrollViewDelegate scrollViewWillEndDragging:scrollView withVelocity:velocity targetContentOffset:targetContentOffset];
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]) {
        [scrollViewDelegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
    }
}

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)]) {
        return [scrollViewDelegate scrollViewShouldScrollToTop:scrollView];
    }
    return TRUE;
}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidScrollToTop:)]) {
        [scrollViewDelegate scrollViewDidScrollToTop:scrollView];
    }
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewWillBeginDecelerating:)]) {
        [scrollViewDelegate scrollViewWillBeginDecelerating:scrollView];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)]) {
        [scrollViewDelegate scrollViewDidEndDecelerating:scrollView];
    }
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(viewForZoomingInScrollView:)]) {
        return [scrollViewDelegate viewForZoomingInScrollView:scrollView];
    }
    return nil;
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewWillBeginZooming:withView:)]) {
        [scrollViewDelegate scrollViewWillBeginZooming:scrollView withView:view];
    }
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidEndZooming:withView:atScale:)]) {
        [scrollViewDelegate scrollViewDidEndZooming:scrollView withView:view atScale:scale];
    }
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidZoom:)]) {
        [scrollViewDelegate scrollViewDidZoom:scrollView];
    }
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidEndScrollingAnimation:)]) {
        [scrollViewDelegate scrollViewDidEndScrollingAnimation:scrollView];
    }
}

- (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView {
    UIScrollView <UIScrollViewDelegate> *scrollViewDelegate = (UIScrollView <UIScrollViewDelegate> *)self.scrollView;
    if ([scrollViewDelegate respondsToSelector:@selector(scrollViewDidChangeAdjustedContentInset:)]) {
        [scrollViewDelegate scrollViewDidChangeAdjustedContentInset:scrollView];
    }
}