我会推荐PDFAnnotation
比较起来UIView
用于将内容添加到PDFView
.
比较一个并不那么容易UIView's
框架内的PDFView
由于它们的坐标系不同。
添加一个PDFAnnotation
to the PDFView
与 PDF 坐标系同步工作,而使用 UIView 时,您将需要在坐标空间之间进行一些转换,这可能很棘手且不太准确。
以下是我为了使其能够与视图一起使用而所做的一些小更改。
首先在你的SignatoryXibView
我添加了这个功能,当我们靠近边缘时显示红色边框
func showWarning(_ show: Bool)
{
if show
{
contentView1.layer.borderColor = UIColor.red.cgColor
return
}
contentView1.layer.borderColor = UIColor.green.cgColor
}
我相信SignatoryXibView
不应该负责检测和防止超出其超级视图范围,因此我创建了一个 ViewController 需要遵守的协议,以便它可以防止SignatoryXibView
走出去PDFView
bounds.
protocol SignatoryViewDelegate: class
{
func signatoryView(_ signatoryView: SignatoryXibView,
didReceivePanGesture gesture: UIPanGestureRecognizer)
}
class SignatoryXibView: UIView {
// Add this
weak var delegate: SignatoryViewDelegate?
// .. rest of your code
@objc
func pan(_ gesture: UIPanGestureRecognizer)
{
// Hand off view translation handling to the delegate
self.delegate?.signatoryView(self,
didReceivePanGesture: gesture)
}
}
现在在你的UIView
扩展中,您创建了一个运行良好的翻译方法,但是您不想翻译视图的位置。您需要首先检查平移是否会超出所需的边界并阻止平移的发生。
extension UIView {
// Your original code
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)))
}
// I have added this function to return the new rect
// that would happen if this view translated
func translatedRect(_ translation: CGPoint) -> CGRect
{
// All of this is your calculation
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
var rect = CGRect(origin: .zero,
size: CGSize(width: bounds.width,
height: bounds.height))
let midX = min(maxX, max(minX, destination.x))
let midY = min(maxY ,max(minY, destination.y))
// I am not translating here, just creating a new rect
// of the view if it would be translated
rect.origin = CGPoint(x: midX - frame.width/2,
y: midY - frame.height/2)
return rect
}
}
In your ViewController's loadPDF()
函数,让你的视图控制器成为SignatoryXibView
// Add Sign on PdfView
// Your code unchanged
let customView = SignatoryXibView(frame: CGRect(x: 150,
y: 140,
width: 112,
height: 58))
customView.signatoryLabel.text = "John Doe"
self.pdfView.addSubview(customView)
//Add this
customView.delegate = self
最后,您实现了我们之前在协议中添加的委托函数,以防止SignatoryXibView
防止超出页面范围。
extension ViewController: SignatoryViewDelegate
{
func signatoryView(_ signatoryView: SignatoryXibView,
didReceivePanGesture gesture: UIPanGestureRecognizer)
{
// Get the location where the user has tapped
let gestureTouchLocation = gesture.translation(in: signatoryView)
// Get the new frame if the signature view would
// be translated
let updatedFrame
= signatoryView.translatedRect(gestureTouchLocation)
// Convert this rect from the Signature View's coordinate space
// To the PDFView's coordinate space
let updatedFrameConverted
= pdfView.convert(updatedFrame,
to: pdfView.currentPage!)
print("Updated frame: \(updatedFrame)")
print("Updated frame converted: \(updatedFrameConverted)")
print("Signature frame: \(signatoryView.frame)")
print()
// Retrieve the bounds of the current page
// Handle the optional properly in your production app
let pageRect = pdfView.currentPage!.bounds(for: .mediaBox)
// Check if the new frame of SignatoryXibView is within the bounds of the pdf page
if updatedFrameConverted.origin.x > CGFloat.zero &&
updatedFrameConverted.origin.y + updatedFrameConverted.height < pageRect.height &&
updatedFrameConverted.origin.x + updatedFrameConverted.width < pageRect.width &&
updatedFrameConverted.origin.y > CGFloat.zero
{
// Since the view is within the bounds, you can update the views frame
signatoryView.translate(gesture.translation(in: signatoryView))
gesture.setTranslation(.zero, in: signatoryView)
signatoryView.setNeedsDisplay()
// Do not show any warning
signatoryView.showWarning(false)
return
}
// The view has reached the edge of the page so do not perform any view
// translation and show the warning
signatoryView.showWarning(true)
}
}
最终结果应该为您提供以下结果,这可以防止视图超出页面边界并使视图变为红色以表明它无法进一步移动:
最后的想法
- 我建议使用
PDFAnnotation
将内容添加到 PDF 时
- 这将正确缩放和滚动页面,特别是在缩放 PDF 等情况下,您可能需要再次更新视图才能使其位于正确的位置
Update
我更新了一些数学func signatoryView
函数在extension ViewController: SignatoryViewDelegate
这应该会给你更好的结果来找出正确的边界,并且当你缩放时它也会起作用:
但是,由于它不是作为注释添加的,因此它不会随页面滚动,但会在下一页上观察到相同的边界。