Как использовать карандашную (например, рукописную) аннотацию и сенсорную навигацию в PDFKit одновременно на iOS (Swift)? - PullRequest
0 голосов
/ 22 мая 2018

Я написал приложение для аннотаций в PDF в Swift с PDFKit, которое использует touchesBegan / Moved / Ended для создания аннотаций в PDF.Прекрасно работает для рисования аннотаций.

Чтобы получить события касания карандашом, мне нужно было сделать кнопку переключения, чтобы установить «isUserInteractionEnabled = false» в PDFView, если я делаю аннотации и устанавливаю «isUserInteractionEnabled = true» для навигации(панорамирование / масштабирование) документа PDF.При «isUserInteraction = true» все сенсорные события «съедаются» PDFView (я думаю, что это просмотр документов Scrollview) и никогда не вызываются в ViewController.

Постоянное переключение действительно раздражает пользователя и неМожно использовать.

Так как же использовать переопределения touchesBegan / Moved / Ended в ViewController и иметь возможность перемещаться (панорамирование / масштабирование) в PDF без касания пальцами без переключения isUserInteractionEnabled все время?

Приложение должно работать на iPad только карандашом.

Спасибо, что нашли время, Ларс

Пример реализации, чтобы прояснить ситуацию: (внутри класса ViewController: UIViewController)

override func viewDidLoad() {
    super.viewDidLoad()

    pdfView = PDFView()

    pdfView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(pdfView)

    pdfView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    pdfView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    pdfView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    pdfView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    let url = Bundle.main.url(forResource: "TestPDF", withExtension: "pdf")!
    pdfView.document = PDFDocument(url: url)

    pdfView.isUserInteractionEnabled = false //touches events are called ... annotation with pencil mode
    //pdfView.isUserInteractionEnabled = true //touches events are NEVER called ... but pan/zoom works
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("touchesBegan called!")

    if let touch = touches.first {
        if touch.type == .stylus {
            print("touchesBegan pencil annotation ...")
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("touchesMoved called!")

    if let touch = touches.first {
        if touch.type == .stylus {
            print("touchesMoved pencil annotation ...")
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("touchesEnded called!")

    if let touch = touches.first {
        if touch.type == .stylus {
            print("touchesEnded pencil annotation ...")
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Может быть поздно, но я просто оказался в точно такой же ситуации.Итак, я нашел пример кода Apple: Использование сенсорного ввода для приложений рисования !И закончил с созданием собственного распознавателя жестов.Это все еще очень альфа-код, но вы поймете идею:

class PDFDrawingGestureRecognizer: UIGestureRecognizer {
weak var pdfView: PDFView!
private var lastPoint = CGPoint()
private var currentAnnotation : PDFAnnotation?


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first,
        let numberOfTouches = event?.allTouches?.count,
        numberOfTouches == 1 {
        state = .began

        let position = touch.location(in: pdfView)
        let convertedPoint = pdfView.convert(position, to: pdfView.currentPage!)

        lastPoint = convertedPoint
    } else {
        state = .failed
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    state = .changed

    guard let position = touches.first?.location(in: pdfView) else { return }
    let convertedPoint = pdfView.convert(position, to: pdfView.currentPage!)

    let path = UIBezierPath()
    path.move(to: lastPoint)
    path.addLine(to: convertedPoint)
    lastPoint = convertedPoint

    if currentAnnotation == nil {
        let border = PDFBorder()
        border.lineWidth = 10
        border.style = .solid

        currentAnnotation = PDFAnnotation(bounds: pdfView.bounds, forType: .ink, withProperties: [
            PDFAnnotationKey.border: border,
            PDFAnnotationKey.color: UIColor.red,
            PDFAnnotationKey.interiorColor: UIColor.red,
            ])
        let pageIndex = pdfView.document!.index(for: pdfView.currentPage!)
        pdfView.document?.page(at: pageIndex)?.addAnnotation(currentAnnotation!)
    }
    currentAnnotation!.add(path)


}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let position = touches.first?.location(in: pdfView) else {
        state = .ended
        return
    }

    let convertedPoint = pdfView.convert(position, to: pdfView.currentPage!)

    let path = UIBezierPath()
    path.move(to: lastPoint)
    path.addLine(to: convertedPoint)

    currentAnnotation?.add(path)
    currentAnnotation = nil

    state = .ended
}
}

Наконец, добавьте этот распознаватель жестов в ваш PDFView.Если вы хотите, чтобы распознаватель жестов работал только с карандашом, в методе touchesBegan проверьте происхождение касания.

0 голосов
/ 22 мая 2018

Вы можете реализовать все свои операции рисования в UIGestureRecognizer PDFView и также реализовать этот метод.

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
{
    if touch.type == .stylus
    {
        return true
    }
    else
    {
        return false
    }
}
...