I am making a code that uses pencilKit and you can draw on the canvas. However, I want to be able to detect if the resulted drawing is in contact with a Rectangle().
Is there any way to do this?
I dont want to use variables for X and Y positions because I have more than 400 rectangles in a grid.
PencilKit
RSS for tagCapture touch input as an opaque drawing and turn it into high-quality images that can be displayed on iOS and macOS using PencilKit.
Posts under PencilKit tag
35 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Has anyone got PKToolPicker appearing in an iPad app running in compatibility mode on Vision Pro?
In our app, it appears fine on iPad, but not in the Vision Pro simulator.
Even though the tools do not appear, I am able to draw in the canvas (...though not change the pen, of course).
I did not read anywhere that it was not supported on Vision Pro. I only saw that interactions with pencil do not work, but that other forms of interaction (eg drawing with touch) should work.
Anyone seen it working on Vision Pro?
I have a question about an app using PencilKit.
I would like to add a UIImageView that is addSubviewed on top of PKCanvasView to PKDrawing and retrieve it as data along with other drawing information using dataRepresentation().
Please tell me how.
I have a question about an app using PencilKit.
I would like to add a UIImageView that is addSubviewed on top of PKCanvasView to PKDrawing and retrieve it as data along with other drawing information using dataRepresentation().
Please tell me how.
Hi,
I encounter various problems with inserting PKDrawing into a PDFAnnotation :
First : After "page.addAnnotation(myCustomAnnotation)", saved document seems corrupted (affected pages are displayed with a "X" watermark covering the whole page),
Second : The only way to extract PKDrawing from the annotation is unarchiveTopLevelObjectWithData: which is deprecated,
Final : I'm not able to re-read PKDrawings to restore PKCanvasView undoManager.
Does anyone have an idea on a correct way to do this?
Thank you in advance and happy new year everyone!
I'm trying to add rotation functionality to the PKCanvasView, so that rotation gesture rotates the drawing, I want it to be working together with zoom gesture too, which is already implemented in the PKCanvasView.
Rotation works reasonably fine when rotation and zoom can't be performed simultaneously. The moment I enable simultaneous zoom+rotation performance of rotation gets noticably bad. Visually it looks like rotation only happens on noticable angles like 10,20,30.. degrees which looks choppy. Zoom at the same time looks smooth as before. I'm trying to understand why and how to fix this.
The rotation gesture handler is here:
@objc
func handleRotation(_ gesture: UIRotationGestureRecognizer) {
guard let curView = gesture.view as? PKCanvasView else {return}
if gesture.state == .began || gesture.state == .changed {
let rotation = gesture.rotation
let gestureCenter = gesture.location(in: curView)
let center = CGPoint(x: gestureCenter.x / curView.zoomScale, y: gestureCenter.y / curView.zoomScale)
let finalTransform = CGAffineTransform(translationX: -center.x, y: -center.y)
.concatenating(CGAffineTransform(rotationAngle: rotation))
.concatenating(CGAffineTransform(translationX: center.x, y: center.y))
curView.drawing.transform(using: finalTransform)
gesture.rotation = 0
}
}
which just constructs rotation matrix around rotation gesture center and calls curView.drawing.transform(using: finalTransform). Rotation matrix is correct I think because without simultaneous zoom+rotation it rotates everything as intended and smoothly under any zoom. (Just for clarity: in the rotation handler the matrix does only the rotation, zoom is done in pinch gesture handler implemented by the PKCanvasView. The zoomScale is used in estimations only to figure out the content coodrinate).
The handleRotation method is set as
let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation))
rotationGestureRecognizer.delegate = self
canvasView.addGestureRecognizer(rotationGestureRecognizer)
The simultaneous handling of zoom+rotation I enable with this code:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
What I've tried:
Tried to nable simultaneous recognition only for zoom+rotation (without the pan gesture and possible others), the effect is the same. For example rotation+pan work smoothly together.
I've verified that the gesture handler is called very often, every 8-16 milliseconds (rotation matrix creation and curView.drawing.transform(using: finalTransform) is included in this time period) which should be enough for visually smooth rotation.
Other observations:
When zoom and rotation both are enabled the rotation sometimes gets completely stuck, zoom and pinch is responsive but rotation is not happening visually. Only when I release fingers from the screen the rotation unstucks and content is rotated as if it didn't stuck at all. During the "stuck" period the rotation handler is called with the same frequency it's just not being visually reflected.
Other thoughts:
It kind of looks like the tranformation I set in the rotation handler gets overwritten by transformation from the zoom handler. But pan+rotation works fine together which confuses this theory.
When I display the PKToolPicker in my app it looks similar to the image below
If you use one of the apps from Apple like Pages or Freeform you see a picker similar to this one.
Notice that the PKToolPicker from the Apple app has 6 tools not including the ruler. With the tool all the way to the left being the writing tool.
How do you get the picker to display with the writing tool? I have looked over the API and I can see where you can set if the ruler is displayed or not but I can't find anything for the writing tool
Hello. I am developing an app that helps people with language issues communicate and for that I thought I could do a custom keyboard for them.
I was wondering if there is a way of doing a 3rd party keyboard using SwiftUI (little to no UIKit) and if so, where can I find documentation/tutorials.
I have looked with no success.
Additionally, can we use a PKCanvasView inside of keyboards (ie, is there any restriction/policy)? I intend to use it so that users can draw the words they're looking for (I already have the model and know how to come up with the suggestions and everything)
Thanks a lot!
Running my app in iOS 17 has a weird bug. I can draw as usual on my canvas, but only when I open the color picker from the toolPicker a bunch of weird errors and warnings are posted to the console (I am assuming they are related to it.) Closing the color picker and leaving the screen would normally dismiss the toolbar, but now it stays forever and on every screen. Interestingly the canvas, the tool picker and the viewController are all getting deinitialized, which means there is a second/new toolPicker on screen and I have no reference to it.
Here are the mentioned warnings and errors:
Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)" UserInfo={NSLocalizedFailureReason=(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)}>
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
elapsedCPUTimeForFrontBoard couldn't generate a task port
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
elapsedCPUTimeForFrontBoard couldn't generate a task port
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
elapsedCPUTimeForFrontBoard couldn't generate a task port
No setting found for property named "_UISceneHostingClientSettingsExtension"
No setting found for property named "_UISceneHostingClientSettingsExtension"
No setting found for property named "_UISceneHostingClientSettingsExtension"
A code snippet, but nothing fancy:
private var imageCanvasView = ImageCanvasView()
private var toolPicker = ToolPicker()
override func viewDidLoad() {
super.viewDidLoad()
self.toolPicker.setVisible(true, forFirstResponder: self.imageCanvasView)
self.toolPicker.addObserver(self.imageCanvasView)
self.imageCanvasView.becomeFirstResponder()
}
Any ideas on how to prevent that or at least access/hide the permanent tool picker?
I've been trying to disable the "Smart Selection" feature introduced in https://developer.apple.com/wwdc20/10107 from a PKCanvasView. This feature could be very useful for some apps but if you want to start from a clean state canvas it might get in your way as you add gestures and interactions.
Is there any way to opt out from it?
The #WWDC20-10107 video demonstrates the "Smart Selection" feature at around 1:27.
DemoCode:
import SwiftUI
import UIKit
import PencilKit
class PencilKitViewController: UIViewController, PKCanvasViewDelegate, PKToolPickerObserver {
lazy var canvasView: PKCanvasView = {
let canvasView = PKCanvasView()
canvasView.drawingPolicy = .anyInput
canvasView.translatesAutoresizingMaskIntoConstraints = false
return canvasView
}()
lazy var toolPicker: PKToolPicker = {
let toolPicker = PKToolPicker()
toolPicker.showsDrawingPolicyControls = true
toolPicker.addObserver(self)
return toolPicker
}()
let drawing = PKDrawing()
override func viewDidLoad() {
super.viewDidLoad()
canvasView.drawing = drawing
canvasView.delegate = self
view.addSubview(canvasView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
canvasView.frame = view.bounds
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
toolPicker.setVisible(true, forFirstResponder: canvasView)
toolPicker.addObserver(canvasView)
canvasView.becomeFirstResponder()
}
// canvas
func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
print("drawing")
}
func canvasViewDidFinishRendering(_ canvasView: PKCanvasView) {
}
func canvasViewDidEndUsingTool(_ canvasView: PKCanvasView) {
}
func canvasViewDidBeginUsingTool(_ canvasView: PKCanvasView) {
}
}
// UIRepresentable for SwiftUI
struct PencilKitView: UIViewControllerRepresentable {
class Coordinator {
var parentObserver: NSKeyValueObservation?
}
var onSubmit: ((UIImage?, Error?) -> Void)? = .none
func makeUIViewController(context: Context) -> PencilKitViewController {
let pencilKitViewController = PencilKitViewController()
context.coordinator.parentObserver = pencilKitViewController.observe(\.parent, changeHandler: { vc, _ in
})
return pencilKitViewController
}
func updateUIViewController(_ uiViewController: PencilKitViewController, context: Context) {
}
func makeCoordinator() -> Self.Coordinator { Coordinator() }
}
struct ContentView: View {
var onSubmit: ((UIImage?, Error?) -> Void)? = .none
var body: some View {
PencilKitView()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
iOS:
macCatalyst:
In the recent WWDC 2022, FreeForm app was introduced and in that app in the tool picker there was a Fill Tool.
I want to put that fill tool (or any similar filling tool) in my xcode app that I am building. But when I use pencilkit PKToolPicker, there is not Fill Tool.
So how to get this fill tool in my app.
Any leads would be helpful. Thanks.
Hi,
can i create custom tool for PKToolPicker?
On documentation page on PKTool says "Don’t adopt this protocol in your own objects. Instead, create a tool object to provide users with the desired the tool behavior."
Best regards,
Matej Klemen
on iOS, I want to add up undo/redo and a close button. On ipadOS, I only need to add a close button
What’s your experience in adding a close button to the ToolPicker? Or at least have the position of the window so I can add an overlapping box (even on floating).
Hey guys,
Is there a native bridge between a PKStrokePath and other path objects like CGPath, UIBezierPath or even SwiftUI Path ?