Search code examples
iosswiftpencilkit

How to set constant width of strokes from PKInkingTool in PencilKit


When drawing on screen using finger/pencil with the PencilKit API, I would like to set the width of strokes to be a constant. Currently, the width setting in say PKInkingTool only sets the baseline width when drawing with finger or pencil, and the width varies if one does slow or fast strokes with their finger/pencil.

I'm not sure how to setup a minimum example, there is a lot of code to get a PencilKit View working. You can use this example from Apple to setup a simple drawing app.

Here's my code to choose a default tool for drawing:

canvas.tool = PKInkingTool(.pen, color: .white, width: 10)

where canvas is a PKCanvasView object. There is a validWidthRange property within each InkType (link to docs) but I'm unsure if this is what can help me achieve what I want.


Solution

  • I have found a solution (thanks to Will Bishop), however I'm not sure it's the best for everyone. I solve it by redrawing the stroke after its been completed with a constant width. Apple released new APIs for PKStroke and PKStrokePoint at WWDC2020 for iOS 14. Here's the relevant section of my code (newDrawing is the new drawing with constant stroke width, while canvasView refers to the current drawing on my PKCanvas):

    var newDrawingStrokes = [PKStroke]()
        for stroke in canvasView.drawing.strokes {
            var newPoints = [PKStrokePoint]()
            stroke.path.forEach { (point) in
            let newPoint = PKStrokePoint(location: point.location, 
                                         timeOffset: point.timeOffset, 
                                         size: CGSize(width: 5,height: 5), 
                                         opacity: CGFloat(1), force: point.force,
                                         azimuth: point.azimuth, altitude: point.altitude)
            newPoints.append(newPoint)
            }
            let newPath = PKStrokePath(controlPoints: newPoints, creationDate: Date())
            newDrawingStrokes.append(PKStroke(ink: PKInk(.pen, color: UIColor.white), path: newPath))
         }
    let newDrawing = PKDrawing(strokes: newDrawingStrokes)
    

    This is some preliminary code that I threw together, so if you find any bugs/mistakes do let me know!