我的应用程序使用PDFKit显示 PDF 文件,并允许用户通过我自己的代码使用UIKit和CoreGraphics框架对 pdf 文件进行注释。由于我想使用PencilKit框架来更好地进行注释,因此我正在实施该PencilKit框架,但我发现了一些我遇到的问题。
我所做的是添加PKCanvasView在DocumentView一个PDFView的。从本质上讲,它工作正常,我可以使用 的工具进行注释,PencilKit并且可以浏览 PDF 的页面。
当我放大 PDF 页面时出现问题。由于PKCanvasView没有在 内部缩放本身DocumentView,因此墨水注释显示为像素化。的PKCanvasView,因为它的变焦并没有改变没有重绘其与新的规模内容,并且更新contentScaleFactor使图更清晰不起作用。
另一个问题是,在某种程度上与前一个相关,由于应用程序适合每个 PDF 页面以使用所有屏幕,这使得UIScrollView包含DocumentViewPDFView 的 的缩放功能因 PDF 页面的大小而异. 这使得如果我打开一个有小页面的 PDF 和另一个大页面的 PDF,就大小(宽度 x 高度)而言,即使我选择了最小的,我也会看到不同大小的墨迹工具的线条宽度PKToolPicker两个文件的线宽。
所以我想知道是否可以将 aPKCanvasView和 PDFView 分别添加到UIViewController’s视图中,因此它们都具有相同的superview,具有相同的 ContentSize 和最大/最小缩放级别,并且在平移和缩放 时PKCanvasView,PDFView 也是如此。
无论如何,如果有解决方法,我很乐意知道。;)
例如,如果我使用 Notes 应用程序进行绘图,我可以看到有一个可用于手写的自定义工具。现在就我而言,我不想实现手写,但我需要一个自定义工具,可以用来绘制箭头等元素。简而言之,我需要一支可裁剪的铅笔,它可以让我检测触摸并通过读取触摸来直接绘图。
\n现在,如果我阅读PKTool文档,它会说:
\nDon\xe2\x80\x99t adopt this protocol in your own objects. Instead, create a tool object to provide users with the desired the tool behavior.\nRun Code Online (Sandbox Code Playgroud)\n但只有一组预定义的工具。是否可以像 Notes 应用程序一样实现我自己的工具?
\n\n我正在尝试在画布上使用 ToolPicker,但这里有:
如何将文本、形状添加到画布上的 ToolPicker 中?
struct MyCanvas: UIViewRepresentable {
var canvasView: PKCanvasView
let picker = PKToolPicker.init()
func makeUIView(context: Context) -> PKCanvasView {
self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
self.canvasView.isOpaque = false
self.canvasView.backgroundColor = UIColor.clear
self.canvasView.becomeFirstResponder()
let imageView = UIImageView(image: UIImage(named: "badmintoncourt"))
let subView = self.canvasView.subviews[0]
subView.addSubview(imageView)
subView.sendSubviewToBack(imageView)
return canvasView
}
func updateUIView(_ uiView: PKCanvasView, context: Context) {
picker.addObserver(canvasView)
picker.setVisible(true, forFirstResponder: uiView)
DispatchQueue.main.async {
uiView.becomeFirstResponder()
}
}
}
Run Code Online (Sandbox Code Playgroud) 如何设置 PKToolPicker 初始位置?
它总是从底部开始,如果有工具栏,则覆盖工具栏。
let toolPicker = PKToolPicker.shared(for: self.view.window!)
toolPicker?.addObserver(canvas)
toolPicker?.setVisible(true, forFirstResponder: canvas)
Run Code Online (Sandbox Code Playgroud) 我试图弄清楚如何修改PKDrawing属性PKCanvasView以添加一些形状,如圆形或至少添加一条线,但是它PKDrawing是一种不透明的类型,所以没有太多事情要做。
是否有任何解决方法可以在 a 上创建形状或线条PKCanvasView?
在暗模式下,PKInkingTool 中设置的所有颜色似乎都在亮度上反转。如果我选择亮红色,我会得到深红色,反之亦然。
例如,如果我使用 UIColorPickerViewController 来选择颜色:
PKInkingTool(.pencil, color:color, width:10)
Run Code Online (Sandbox Code Playgroud)
PKCanvasView 中显示的颜色不是正确的颜色。似乎可行的唯一方法是不支持暗模式。
overrideUserInterfaceStyle = .light
Run Code Online (Sandbox Code Playgroud)
有没有办法让 PencilKit 使用正确的颜色而不是自动转换颜色?
我正在尝试将 Apple Pencil 与 WKWebView 集成。
期望的行为:
因此,在花了更多的时间之后,我得到了一个非常hacky的解决方案,而且我实际上不喜欢这个解决方案:
WKWebView透明的。PKCanvasViewhitTestPKCanvasView 的始终返回 nil。drawingGestureRecognizer将PKCanvasView添加到WKWebViewdrawingGestureRecognizer.allowedTouchTypes = [NSNumber(value: UITouch.TouchType.pencil.rawValue)]设置为PKCanvasView这种方法有效,但它消除了实现的大量灵活性。
到目前为止我已经尝试了两种方法:
当我检测到画布上的用户输入来自手指时,有选择地取消用户输入。这不起作用,因为在事件被视图消耗之前我无法检测到这一点。
创建一个透明的超级视图,并在我进行检测时手动为 PKCanvasView 和 WKWebView 调用 TouchesBegan/touchesMoved/touchesEnded 。不幸的是,这也不起作用,因为调用这些方法没有执行任何操作。
这是我到目前为止的一些基本代码:
struct SUICanvasView: UIViewControllerRepresentable {
let url: URL?
func makeUIViewController(context: Context) -> ZRCanvasReader {
let canvasReader = ZRCanvasReader()
canvasReader.openUrl(url: url)
return canvasReader
}
func updateUIViewController(_ uiViewController: ZRCanvasReader, context: Context) {
}
typealias UIViewControllerType = ZRCanvasReader …Run Code Online (Sandbox Code Playgroud) 当使用 PencilKit API 使用手指/铅笔在屏幕上绘图时,我想将笔画的宽度设置为常量。目前,宽度设置仅PKInkingTool设置用手指或铅笔绘图时的基线宽度,并且如果用手指/铅笔缓慢或快速描画,则宽度会发生变化。
我不确定如何设置一个最小的示例,有很多代码可以让 PencilKit 视图正常工作。您可以使用Apple 的此示例来设置一个简单的绘图应用程序。
这是我选择默认绘图工具的代码:
canvas.tool = PKInkingTool(.pen, color: .white, width: 10)
Run Code Online (Sandbox Code Playgroud)
其中canvas是一个PKCanvasView对象。validWidthRange每个 InkType都有一个属性(链接到文档),但我不确定这是否可以帮助我实现我想要的。
目前,我可以在点击按钮时显示一个单独的PKCanvasView和 a 。PKToolPicker但是,该工具不会在选取器和画布视图之间传输。有谁知道如何链接两者,以便当我更改选择器中的工具时,该工具也会在画布视图中更新?我在下面附上了我的代码。谢谢你!
import SwiftUI
import PencilKit
struct DrawingView: View {
@State private var showPicker = false
@State private var canvasView = PKCanvasView()
var body: some View {
VStack {
PencilKitView(isActive: $showPicker, canvasView: $canvasView)
Button("Picker") { self.showPicker.toggle() }
}
}
}
struct PencilKitView: UIViewRepresentable {
typealias UIViewType = PKCanvasView
@Binding var isActive: Bool
@Binding var canvasView: PKCanvasView
let coordinator = Coordinator()
class Coordinator: NSObject, PKToolPickerObserver {
func toolPickerSelectedToolDidChange(_ toolPicker: PKToolPicker) {
// some code
}
func …Run Code Online (Sandbox Code Playgroud) 我试图将 a 放在PKCanvasView图像之上,这与初始布局配合良好,但是当调整视图大小(通过旋转 iPad)时,内部PKDrawing不会缩放,这会导致图像注释位于不正确的位置。我正在努力弄清楚如何正确缩放PKDrawing以保留正确的位置。
这是演示该问题的示例:
class ImageDrawingView: UIView {
private let imageView = UIImageView(frame: .zero)
private let drawingView = PKCanvasView(frame: .zero)
private let toolPicker = PKToolPicker()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
// Setup image view
addSubview(imageView)
imageView.image = UIImage(named: "TestImage") // Here I just used a screen grab of the lock screen
imageView.contentMode = .scaleAspectFill
// Setup drawing view …Run Code Online (Sandbox Code Playgroud)