gpt4 book ai didi

ios - 限制在 PDF 页面边界内移动/拖动 pdf 注释

转载 作者:行者123 更新时间:2023-12-05 02:33:21 25 4
gpt4 key购买 nike

我正在使用 PDF 套件库在 PDF View 中加载一个 PDF。我在 pdf View 上添加了一个自定义 View (与 PDF 注释相同),我允许用户使用 UIPanGestureRecognizer 在 pdf View (在 pdf View /容器 View 内)上移动/拖动该自定义 View 。这是一个 gif,

如果您看到这张 gif,就说明有一个问题。该自定义 View 超出了 pdf 页面。我想限制它。自定义 View 应仅在 pdf 页面内移动/拖动。我该如何解决这个问题?有解决办法吗?

这是链接示例项目和所有代码 - https://drive.google.com/file/d/1Ilhd8gp4AAxB_Q9G9swFbe4KQUHbpyGs/view?usp=sharing

这是项目中的一些代码示例,

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)")
}

和用作扩展的代码

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)))
}
}

代码——获取PDF页面的高度和宽度

 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)!)

最佳答案

我会推荐 PDFAnnotation 而不是 UIView 来将内容添加到 PDFView

PDFView 中比较 UIView 的 框架并不是那么容易,因为它们的坐标系不同。

PDFAnnotation 添加到 PDFView 与 PDF 坐标系同步工作,而使用 UIView 时,您需要在坐标空间之间进行一些转换,这可以是棘手且不太准确。

PDFKit PDFView coordinate system add PDF Annotation UIView

我做了一些小改动,以使其与 View 一起工作。

首先在你的SignatoryXibView中我添加了这个函数来在我们靠近边缘时显示红色边框

func showWarning(_ show: Bool)
{
if show
{
contentView1.layer.borderColor = UIColor.red.cgColor
return
}

contentView1.layer.borderColor = UIColor.green.cgColor
}

我认为 SignatoryXibView 不应该负责检测和防止超出其 super View 范围,因此我创建了一个 ViewController 需要遵守的协议(protocol),以便它可以防止 SignatoryXibView 超出 PDFView 范围。

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 扩展中,您创建了一个运行良好的翻译方法,但是您不想翻译 View 的位置。您首先要检查翻译是否会超出所需边界并防止翻译发生。

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
}
}

在您的 ViewController 的 loadPDF() 函数中,让您的 View Controller 成为 SignatoryXibView 的委托(delegate)

// 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

最后,您将实现我们之前在协议(protocol)中添加的委托(delegate)函数,以防止 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)
}
}

最终结果应该给你下面的结果,它防止 View 超出页面边界并使 View 变红以表明它不能再进一步:

PDFKit PDFView prevent Annotation boundary UIView margins

最后的想法

  1. 我建议在向 PDF 添加内容时使用 PDFAnnotation
  2. 这将正确地缩放和滚动页面,特别是在缩放 PDF 等场景中,您可能需要再次更新 View 以使其位于正确的位置

更新

我在 extension ViewController: SignatoryViewDelegate

func signatoryView 函数中更新了一些数学运算

这应该会在确定正确边界方面为您提供更好的结果,并且在您缩放时它也会起作用:

PDFView UIView boundary annotation page width page height

但是,由于它没有作为注释添加,它不会随页面滚动,但在下一页会观察到相同的边界。

关于ios - 限制在 PDF 页面边界内移动/拖动 pdf 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71015338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com