- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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 时,您需要在坐标空间之间进行一些转换,这可以是棘手且不太准确。
我做了一些小改动,以使其与 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 变红以表明它不能再进一步:
最后的想法
PDFAnnotation
更新
我在 extension ViewController: SignatoryViewDelegate
func signatoryView
函数中更新了一些数学运算
这应该会在确定正确边界方面为您提供更好的结果,并且在您缩放时它也会起作用:
但是,由于它没有作为注释添加,它不会随页面滚动,但在下一页会观察到相同的边界。
关于ios - 限制在 PDF 页面边界内移动/拖动 pdf 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71015338/
只是想知道 Jquery Mobile 是否足够稳定以用于实时生产企业移动应用程序。 有很多 HTML5 框架,因为我们的团队使用 JQuery 已经有一段时间了,我们更愿意使用 Jquery 移动框
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 3 年前。 Improve t
所以我尝试在 JavaScript 中对元素进行拖放。我使用的视频教程在这里; https://www.youtube.com/watch?v=KTlZ4Hs5h80 。我已经按照它的说明进行了编码,
无法在移动 iOS(safari 和 chrome)上自动播放以前缓存的 mp3 音频 我正在 Angular 8 中开发一个应用程序,在该应用程序的一部分中,我试图在对象数组中缓存几个传入的音频 m
Git 基于内容而不是文件,所以我目前理解以下行为,但我想知道是否有特殊选项或 hack 来检测此类事情: git init mkdir -p foo/bar echo "test" foo/a.tx
我正在寻找语义 ui 正确的类来隐藏例如移动 View 中的 DIV。在 Bootstrap 中,我们有“visible-xs”和“hidden-xs”。 但是在语义ui上我只找到了“仅移动网格” 最
我正在使用 ubuntu 和 想要移动或复制大文件。 但是当我与其他人一起使用服务器时,我不想拥有所有内存并使其他进程几乎停止。 那么有没有办法在内存使用受限的情况下移动或复制文件? 最佳答案 如果你
这些指令有什么区别?以 ARM9 处理器为例,它不应该是: ASM: mov r0, 0 C: r0 = 0; ASM: ld r0, 0 C: r0 = 0; ? 我不知道为什么要使用一个或另一个:
我有一个文件夹,其中包含一些随机命名的文件,其中包含我需要的数据。 为了使用数据,我必须将文件移动到另一个文件夹并将文件命名为“file1.xml” 每次移动和重命名文件时,它都会替换目标文件夹中以前
我经常在 IB/Storyboard 中堆叠对象,几乎不可能拖动其他对象后面的对象而不移动前面的对象。无论如何我可以移动已经选择但位于其他对象后面的对象吗?当我尝试移动它时,它总是选择顶部的对象,还是
几个月前,我看到 Safari 7 允许推送通知,它似乎是一个非常有用的工具,除了我看到的每个示例都专注于桌面浏览,而不是移动设备。 Safari 推送通知是否可以在移动设备上运行,如果没有,是否有计
我有一个简单的 View 模型,其中包含修改后的 ObservableCollection使用 SynchronizationContext.Current.Send在 UI 线程上执行对集合的更改。
关于cassandra创建的数据文件和系统文件的位置,我需要移动在“cassandra.yaml”配置文件中设置的“commitlog_directory”、“data_file_directorie
我有这个代码 $(function() { var message = 'Dont forget us'; var original; var txt1 = ' - '; $(wind
我的客户报告说他的网站有一个奇怪的问题。该网站的 URL 是 your-montenegro.me 在 基于 Android 的浏览器 上加载时,页面底部会出现一个奇怪的空白区域。以下是屏幕截图: 华
我有这个 HTML 标记: Express 300 bsf Sign Up 我需要将元素从 DOM 上的一个
我有一个可重新排序的 TableView (UITableView 实例)。尽管我已经实现了 UITableViewDataSource 方法: tableView:moveRowAtIndexPat
我的客户报告说他的网站有一个奇怪的问题。该网站的 URL 是 your-montenegro.me 在 基于 Android 的浏览器 上加载时,页面底部会出现一个奇怪的空白区域。以下是屏幕截图: 华
我需要在拖放或复制/剪切和粘贴(复制与移动)期间获取操作类型。它是一个 Swing 应用程序,并且实现了 TransferHandle。我在操作结束时需要此信息,在 importData 方法中。 对
我编写了一个具有 add 和 get 方法的 SortedIntList 类。 我调用以下四个方法: SortedIntList mySortedIntList = new SortedIntList
我是一名优秀的程序员,十分优秀!