I am loading one PDF on PDF view using the PDF kit library. I added one custome view (same like PDF Annotation) on pdf view, and I am allowing users to move/drag that custom view on pdf view(within pdf view/container view) using UIPanGestureRecognizer. Here is a gif,
If you see this gif, there is one problem. That custom view is going outside of the pdf page. I want to restrict it. The custom view should move/drag within the pdf page only. How I can fix this? Is there a solution for it?
Here is the link sample project and all code - https://drive.google.com/file/d/1Ilhd8gp4AAxB_Q9G9swFbe4KQUHbpyGs/view?usp=sharing
Here is some code sample from project,
override func didMoveToSuperview() {
addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan)))
}
@objc func pan(_ gesture: UIPanGestureRecognizer) {
translate(gesture.translation(in: self))
gesture.setTranslation(.zero, in: self)
setNeedsDisplay()
print("Frames after moving : \(frame)")
}
and code used as an extension
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)))
}
}
Code - Get PDF Page Height and Width
let page = pdfDocument.page(at: 0)
let pageRect = page?.bounds(for: .mediaBox)
print("pdf page width =", (pageRect?.size.width)!, "pdf page height =", (pageRect?.size.height)!)
I would recommend
PDFAnnotationrather thatUIViewfor adding content onto thePDFView.It is not so easy to compare a
UIView'sframe within aPDFViewdue to their coordinate systems being different.Adding a
PDFAnnotationto thePDFViewworks in sync with the PDF coordinate system whereas working with UIView, you will need to do some conversions between coordinate spaces and this can be tricky and not so accurate.Here are some small changes I made to kind of get this to work with a view.
First in your
SignatoryXibViewI added this function to show a red border when we are close to the edgeI believe the
SignatoryXibViewshould not be responsible for detecting and preventing going out of its superviews bounds so I created a protocol which the ViewController needs to conform to so that it can prevent theSignatoryXibViewgoing out of thePDFViewbounds.Now in your
UIViewextension, you created a translate method which works well however, you do not want to translate the view's location. You want to first check if the translation will go out of the desired boundary and prevent the translation from happening.In your
ViewController's loadPDF()function, make your view controller the delegate of theSignatoryXibViewThen finally you implement the delegate function we added earlier in the protocol to prevent the
SignatoryXibViewfrom going out the page's bounds.The end result should give you the below result which prevents the view from going outside the page bounds and makes the view red to show it cannot go further:
Final thoughts
PDFAnnotationwhen adding things to the PDFUpdate
I updated some math in the
func signatoryViewfunction in theextension ViewController: SignatoryViewDelegateThis should give you better results in terms of figuring out the right boundary and also it will work when you zoom:
However, since it is not added as an annotation, it will not scroll with the page but the same boundary will be observed on the next page.