1

What I am doing is that, I took pdf view, it contains one sample pdf. On top of that, I am adding more than 1 signatories(custom view) views, when user click on add button from navigation bar.

Scene 1: When add first Signatory view (customview) on pdf, it is adding add and I can drag/move that first Signatory view (Signatory1) on pdf, this is working fine.

Scene 2: When add second Signatory view (Signatory2 customview) on pdf, it is adding and I can drag/move that second Signatory view (Signatory2) on pdf, this is also working fine, but in this scenario I can't move/drag the first signatory view (Signatory1)

Scene 3: Similarly When add third Signatory view (Signatory3 customview) on pdf, it is adding and I can drag/move that third Signatory view (Signatory3) on pdf, this is also working fine, but in this scenario I can't move/drag the first signatory view (Signatory1) and second signatory view (Signatory2) and so on

The problem is that, I have access to only the current Signatory only (I can move/drag only the current Signatory view which added recently), I can can't able to move/drag old Signatories views.

How I can move/drag any Signatory, according to my choice when I click/touch (drag/move) any specific Signatory view on the pdf view ?

Here is the some code,

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    
        customView1 = SignatoryXibView(frame: CGRect(x: 30, y: 30, width: 112, height: 58))
        customView2 = SignatoryXibView(frame: CGRect(x: 30, y: 30, width: 112, height: 58))
        customView3 = SignatoryXibView(frame: CGRect(x: 30, y: 30, width: 112, height: 58))
        customView4 = SignatoryXibView(frame: CGRect(x: 30, y: 30, width: 112, height: 58))
        customView5 = SignatoryXibView(frame: CGRect(x: 30, y: 30, width: 112, height: 58))
        
        loadPdf()
    
    }
    
    func loadPdf(){
        
        if let path = Bundle.main.path(forResource: "appointment-letter", ofType: "pdf") {
            if let pdfDocument = PDFDocument(url: URL(fileURLWithPath: path)) {
                pdfView.displayMode =  .singlePage // .singlePage //.singlePageContinuous //.twoUp
                //by default display mode is - singlePageContinuous
                pdfView.autoScales = true
                pdfView.displayDirection = .vertical // .horizontal//.vertical
                pdfView.document = pdfDocument
            
                pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleTopMargin, .flexibleBottomMargin]
                pdfView.zoomIn(self)
                pdfView.autoScales = true
                pdfView.backgroundColor = UIColor.white

                //Imp line
                pdfView.usePageViewController(true, withViewOptions: [:])
                
                currentPageNumberOfPdf = self.pdfView.currentPage?.pageRef?.pageNumber ?? 0
                print("Total Pages in PDF : ",pdfDocument.pageCount);
                
                self.pdfView.bringSubviewToFront(customView1!)
            }
        }
        
    }

 @IBAction func addSignatoryButtonClicked(_ sender: Any) {
        
        signatoryCount = signatoryCount + 1
        
        if signatoryCount == 1 {
            customView1?.signatoryLabel.text = "Signatory \(signatoryCount)"
            self.pdfView.addSubview(customView1!)
        }
        else  if signatoryCount == 2 {
            customView2?.signatoryLabel.text = "Signatory \(signatoryCount)"
            self.pdfView.addSubview(customView2!)
        }
        else  if signatoryCount == 3 {
            customView3?.signatoryLabel.text = "Signatory \(signatoryCount)"
            self.pdfView.addSubview(customView3!)
        }
        else  if signatoryCount == 4 {
            customView4?.signatoryLabel.text = "Signatory \(signatoryCount)"
            self.pdfView.addSubview(customView4!)
        }
        else  if signatoryCount == 5 {
            customView5?.signatoryLabel.text = "Signatory \(signatoryCount)"
            self.pdfView.addSubview(customView5!)
        }
    }
    

    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        let touch = touches.first
        let touchLocation = touch?.location(in: self.pdfView)
       // customView1?.center =  touchLocation!
       
        
        if signatoryCount == 1 {
            customView1?.center = touchLocation!
            return
        }
        else  if signatoryCount == 2 {
            customView2?.center = touchLocation!
            return
        }
        else  if signatoryCount == 3 {
            customView3?.center = touchLocation!
            return
        }
        else  if signatoryCount == 4 {
            customView4?.center = touchLocation!
            return
        }
        else  if signatoryCount == 5 {
           customView5?.center = touchLocation!
           return
        }
    
       // frame = view.convert(customView1!.frame, from: pdfView)
       // print("touchesMoved \(frame!.dictionaryRepresentation)")
    
    }

Here is the complete project source code

Nikita Patil
  • 674
  • 1
  • 7
  • 17

1 Answers1

1

You got pretty close. You just need to apply the same approach as I suggested in your last question but respecting the superview's frame.

First add those helpers to your project:


extension  CGPoint {
    static func +(lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        .init(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }
    static func +=(lhs: inout CGPoint, rhs: CGPoint) {
        lhs.x += rhs.x
        lhs.y += rhs.y
    }
}

extension UIView {
    func translate(_ translation: CGPoint) {
        let destination = center + translation
        let minX = frame.width/2
        let minY = frame.height/2
        let maxX = superview!.frame.width-minX
        let maxY = superview!.frame.height-minY
        center = CGPoint(
            x: min(maxX, max(minX, destination.x)),
            y: min(maxY ,max(minY, destination.y)))
    }
}

Second just get rid of the pan gesture recognizer and the correspondent method in your ViewController.

Third change your SignatoryXibView pan gesture to the one below. This will translate the center of the view and respect the frame of its superview:

@objc func pan(_ gesture: UIPanGestureRecognizer) {
    translate(gesture.translation(in: self))
    gesture.setTranslation(.zero, in: self)
    setNeedsDisplay()
}

sample project

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • 1
    Excellent, its working and solved that boundary Issue and moving multiple view on pdf view. @Leo thanks a lot you saved my lot of time, I was trying it for log time. – Nikita Patil Oct 23 '20 at 04:31
  • @NikitaPatil what you need is the view center. The frame is always the same. – Leo Dabus Oct 24 '20 at 04:01
  • Don’t you need to add an annotation instead of a view? You need to add it to the current page of the pdf. Once you add the annotation it will scroll with the document page. I don’t think it will be that easy as dealing with a view. – Leo Dabus Oct 25 '20 at 05:21
  • need to an annotation instead of a view? -Yes but later not now. If I use this custom will scroll with the document page if I made pdf display mode = continuous. I have to replace custom view actual PDF Annotation, that is my next task. Right now I am facing one issue, can you please check it. Here Is the link - https://stackoverflow.com/questions/71015338/restrict-to-move-drag-the-pdf-annotation-within-pdf-page-boundary – Nikita Patil Feb 08 '22 at 15:13