bezierRepresentation
NewiOSmacOSopen var bezierRepresentation: CGPath { get }A Bézier path representation of the path's curve, computed in linear time.
What's New / App UI: SwiftUI, AppKit & UIKit
PencilKit captures Apple Pencil and touch input into strokes and renders them in a canvas view. Apps use it for handwriting, sketching, and annotation surfaces.
The 27 SDK adds 41 APIs with no deprecations or removals. New types include struct RenderState, struct ConvertedBezierPoint, and actor PKStrokeRecognizer. New members include selection, PKContentVersion.version5, erasingStrokePath, strokeID, renderGroupID, renderState, and substroke, plus several new init entry points.
bezierRepresentationopen var bezierRepresentation: CGPath { get }A Bézier path representation of the path's curve, computed in linear time.
erasingStrokePathopen func erasingStrokePath(_ eraserPath: PKStrokePath, mask: UIBezierPath?, transform: CGAffineTransform) -> PKDrawingerasingStrokePathopen func erasingStrokePath(_ eraserPath: PKStrokePath, mask: NSBezierPath?, transform: CGAffineTransform) -> PKDrawinginitpublic init(ink: PKInk, strokePath: PKStrokePath, transform: CGAffineTransform, mask: UIBezierPath?, randomSeed: UInt32, strokeID: UUID, renderGroupID: UUID?, renderState: __PKStrokeRenderState?)initpublic convenience init(controlPoints: [PKStrokePoint], creationDate: Date, strokePathID: UUID)Creates a stroke path with the specified control points and a unique identifier.
@param controlPoints An array of control points for a cubic B-spline. @param creationDate The start time of this path. @param strokePathID The unique identity of the stroke path.
Warning: Using multiple stroke paths with identical IDs but different control points
will result in undefined rendering behavior. Ensure each stroke path has a unique identifier.
initpublic convenience init(bezierPath: CGPath, creationDate: Date, pointProvider: (PKConvertedBezierPointReference) -> PKStrokePoint)Creates a stroke path recreating the specified Bézier path as a cubic uniform B-Spline.
@param bezierPath The Bézier path to convert to a cubic uniform B-Spline. @param creationDate The start time of this path. @param pointProvider Block to initialize the PKStrokePoints of the path. A single PKConvertedBezierPoint instance is shared across all converted points.
The count of control points of the generated spline is not guaranteed to be a specific value except when the provided path is the output of bezierRepresentation->CGPathRef, where it will match the original curve.
The output B-Spline will have continuous curvature and 0 curvature at the endpoints. In cases where the B-Spline cannot fully recreate the Bézier path, it will be an approximation. For example, if the given Bézier path includes line to elements, these will produce straight line segments in the resulting B-Spline, but if a line to element is adjacent to a curve to element, the resulting curve may not match the original.
Warning: For a Bézier path with multiple subpaths, only the first will be converted.
initpublic init(location: CGPoint, timeOffset: TimeInterval, size: CGSize, opacity: CGFloat, force: CGFloat, azimuth: CGFloat, altitude: CGFloat, secondaryScale: CGFloat, threshold: CGFloat, lateralJitter: CGFloat)Creates a stroke point with the specified properties, including lateral jitter.
initpublic init(ink: PKInk, strokePath: PKStrokePath, transform: CGAffineTransform, mask: NSBezierPath?, randomSeed: UInt32, strokeID: UUID, renderGroupID: UUID?, renderState: __PKStrokeRenderState?)lateralJitteropen var lateralJitter: CGFloat { get }The amount of lateral particle jitter at the stroke edge for supported inks.
Lateral jitter applies only to some inks, such as PKInkIdentifierPencil.
PKStrokeextension PKStroke : Identifiableextension PKStroke : Identifiable {
/// The unique identity of the stroke.
@available(iOS 27.0, macOS 27.0, *)
public var id: UUID
/// A type representing the stable identity of the entity associated with
/// an instance.
@available(macOS 27.0, iOS 27.0, *)
public typealias ID = UUID
}PKStrokePathextension PKStrokePath : Identifiableextension PKStrokePath : Identifiable {
/// Creates a stroke path with the specified cubic B-spline control points and a unique identifier.
///
/// - Parameters:
/// - controlPoints: An array of control points for a cubic B-spline.
/// - creationDate: The start time of this path.
/// - id: The unique identity of the path.
///
/// > Warning: Using multiple stroke paths with identical IDs but different control points
/// will result in undefined rendering behavior. Ensure each stroke path has a unique identifier.
@available(iOS 27.0, macOS 27.0, *)
public init<T>(controlPoints: T, creationDate: Date, id: UUID) where T : Sequence, T.Element == PKStrokePoint
/// The unique identity of the stroke path.
///
/// > Warning: Using multiple stroke paths with identical IDs but different control points
/// will result in undefined rendering behavior. Ensure each stroke path has a unique identifier.
@available(iOS 27.0, macOS 27.0, *)
public var id: UUID { get }
/// A type representing the stable identity of the entity associated with
/// an instance.
@available(macOS 27.0, iOS 27.0, *)
public typealias ID = UUID
}PKStrokeRecognizerfinal public actor PKStrokeRecognizerAn actor that recognizes handwritten strokes and searches for text in a drawing.
final public actor PKStrokeRecognizer {
/// A result containing the matched strokes and their bounds from a search query.
public struct SearchResult {
/// The identifiers of the strokes the result contains.
public let strokes: Set<UUID>
/// The bounds of the matched strokes in the coordinate space of their drawing.
public let bounds: CGRect
}
/// The languages the recognizer supports.
public static var supportedLanguages: Set<Locale.Language> { get }
/// The version number of the recognition engine.
///
/// If you persist results this recognizer returns, store this value alongside them
/// and regenerate the results when running on an OS with a higher version number.
public static var recognitionVersion: Int { get }
/// Creates a recognizer with the specified preferred languages.
///
/// Languages are respected on a best-effort basis. Factors such as feature support
/// may affect which languages the recognizer uses.
///
/// - Parameters:
/// - preferredLanguages: A list of languages to recognize ordered by descending priority.
/// Pass nil to use the system languages.
/// The system languages may be used if no listed language is available for recognition.
public init(preferredLanguages: [Locale.Language]? = nil)
/// The drawing the recognizer analyzes.
final public var drawing: PKDrawing { get }
/// Updates the drawing the recognizer analyzes.
///
/// Recognition expects handwriting and strokes scaled as if written on standard paper
/// sizes in points, such as US-letter or A4.
/// - Parameter drawing: The new drawing.
final public func updateDrawing(_ drawing: PKDrawing) async
/// The languages the recognizer uses, ordered by descending priority.
final public var languages: [Locale.Language] { get }
/// A string suitable for indexing the drawing's recognized text in search systems such as Spotlight.
///
/// The string may contain multiple concatenated candidate matches for recognized text in the drawing.
final public var indexableContent: String? { get async }
/// Returns the recognized text from the specified strokes in the drawing.
/// - Parameter strokeIDs: The `id`s of the `PKStrokes` in `drawing` to analyze.
/// Pass `nil` to return the recognized text from the whole drawing.
final public func recognizedText(strokeIDs: Set<UUID>? = nil) async -> String?
/// Searches the drawing for strokes whose recognized text matches the query.
/// - Parameters:
/// - query: The query string to search for.
/// - fullWordsOnly: Restricts matches to whole words only.
/// - caseMatchingOnly: Restricts matches to exact case.
/// - Returns: An array of all results found.
final public func search(_ query: String, fullWordsOnly: Bool = false, caseMatchingOnly: Bool = false) async -> [PKStrokeRecognizer.SearchResult]
@objc deinit
/// Retrieve the executor for this actor as an optimized, unowned
/// reference.
///
/// This property must always evaluate to the same executor for a
/// given actor instance, and holding on to the actor must keep the
/// executor alive.
///
/// This property will be implicitly accessed when work needs to be
/// scheduled onto this actor. These accesses may be merged,
/// eliminated, and rearranged with other work, and they may even
/// be introduced when not strictly required. Visible side effects
/// are therefore strongly discouraged within this property.
///
/// - SeeAlso: ``SerialExecutor``
/// - SeeAlso: ``TaskExecutor``Truncated.
renderGroupIDopen var renderGroupID: UUID? { get }A UUID that groups strokes for wet-ink compositing with compatible inks such as marker.
Set this to the same value for a run of strokes to render them as if drawn while the previous stroke with the same ink was still wet.
renderStateopen var renderState: __PKStrokeRenderState? { get }The render details of the stroke, such as particle positioning. Uses default rendering when nil.
This may be set on substrokes returned by -substrokeWithRange:.
selectionopen var selection: Set<UUID>The identifiers of the strokes selected on the canvas.
strokeIDopen var strokeID: UUID { get }The unique identity of the stroke.
strokePathIDopen var strokePathID: UUID { get }The unique identity of the stroke path.
Warning: Using multiple stroke paths with identical IDs but different control points
will result in undefined rendering behavior. Ensure each stroke path has a unique identifier.
subpathopen func subpath(with range: __PKFloatRange) -> PKStrokePathReturns a copy of the path containing the control points in the specified parametric range.
@param range The parametric range to copy. Values must be within [0, count-1]. @return A new stroke path containing the portion within the specified parametric range.
substrokeopen func substroke(with range: __PKFloatRange) -> PKStrokeReturns a copy of the stroke containing the control points in the specified range.
Maintains rendering information so the returned substroke renders the same as the corresponding portion of the receiver. The returned stroke may have a renderState set to maintain this information.
@param range The range of control points in the receiver to copy to the returned stroke. @returns A new stroke containing only the control points within the specified range.
PKContentVersion.version5case version5 = 5The version that adds stroke render state support.
PKDrawing.erasePathpublic mutating func erasePath(_ eraserPath: PKStrokePath, mask: UIBezierPath? = nil, transform: CGAffineTransform = .identity)PKDrawing.erasePathpublic mutating func erasePath(_ eraserPath: PKStrokePath, mask: NSBezierPath? = nil, transform: CGAffineTransform = .identity)PKDrawing.erasingPathpublic func erasingPath(_ eraserPath: PKStrokePath, mask: UIBezierPath? = nil, transform: CGAffineTransform = .identity) -> PKDrawingPKDrawing.erasingPathpublic func erasingPath(_ eraserPath: PKStrokePath, mask: NSBezierPath? = nil, transform: CGAffineTransform = .identity) -> PKDrawingPKStroke.idpublic var id: UUIDThe unique identity of the stroke.
PKStroke.IDpublic typealias ID = UUIDA type representing the stable identity of the entity associated with an instance.
PKStroke.initpublic init(ink: PKInk, path: PKStrokePath, transform: CGAffineTransform = .identity, mask: UIBezierPath? = nil, randomSeed: UInt32 = UInt32.random(in: 0...UInt32.max), id: UUID = UUID(), renderGroupID: UUID? = nil, renderState: PKStroke.RenderState? = nil)PKStroke.initpublic init(ink: PKInk, path: PKStrokePath, transform: CGAffineTransform = .identity, mask: NSBezierPath? = nil, randomSeed: UInt32 = UInt32.random(in: 0...UInt32.max), id: UUID = UUID(), renderGroupID: UUID? = nil, renderState: PKStroke.RenderState? = nil)PKStroke.renderGroupIDpublic var renderGroupID: UUID?Strokes with certain inks (such as marker) can composite to look as if they were drawn while the previous stroke with the same ink was still wet. This UUID may be set to a single value for a run of strokes which should be rendered together in this manner.
PKStroke.renderStatepublic var renderState: PKStroke.RenderState?Contains information about the render details (such as particle positioning) of this stroke, which can be useful when manipulating the model in certain ways. For example, this may be set on substrokes returned by substroke(range:). nil uses default rendering.
PKStroke.RenderStatepublic struct RenderState : Sendable, Codable, EquatableThe render details of a stroke, including particle positioning and grain texture offset.
Some state is exposed, but other state is opaque. Encode using Codable to persist all stored information.
public struct RenderState : Sendable, Codable, Equatable {
/// The pre-transform position of the grain texture for strokes with a backing grain texture such as crayon.
public var grainOffset: CGPoint?
/// Creates a render state with the specified grain offset.
///
/// - Parameter grainOffset: The grain texture offset. Defaults to nil.
public init(grainOffset: CGPoint? = nil)
/// Creates a `RenderState` from its Objective-C counterpart `PKStrokeRenderState`.
///
/// - Parameter objcValue: The Objective-C `PKStrokeRenderState` to convert from.
public init(_ objcValue: __PKStrokeRenderState)
/// Returns the Objective-C `PKStrokeRenderState` representation of this render state.
public func asObjCRenderState() -> __PKStrokeRenderState
/// Creates a new instance by decoding from the given decoder.
///
/// This initializer throws an error if reading from the decoder fails, or
/// if the data read is corrupted or otherwise invalid.
///
/// - Parameter decoder: The decoder to read data from.
public init(from decoder: any Decoder) throws
/// Encodes this value into the given encoder.
///
/// If the value fails to encode anything, `encoder` will encode an empty
/// keyed container in its place.
///
/// This function throws an error if any values are invalid for the given
/// encoder's format.
///
/// - Parameter encoder: The encoder to write data to.
public func encode(to encoder: any Encoder) throws
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func == (a: PKStroke.RenderState, b: PKStroke.RenderState) -> Bool
}PKStroke.substrokepublic func substroke(range: ClosedRange<CGFloat>) -> PKStrokeReturns a copy of this stroke containing the control points in the given range.
Maintains information for PencilKit rendering to make the copied part of the stroke render the same as the receiver. The returned stroke may have a renderState set to maintain this information.
Parameters
rangeReturnsA new stroke containing only the control points within the specified range.
PKStrokePath.bezierRepresentationpublic var bezierRepresentation: CGPath { get }A Bézier path representation of the path's curve, computed in linear time.
PKStrokePath.ConvertedBezierPointpublic struct ConvertedBezierPointInformation about a B-spline control point converted from a Bézier path.
Provided to the pointProvider closure of init(bezierPath:creationDate:pointProvider:)->Self to initialize each PKStrokePoint-struct of the resulting path.
public struct ConvertedBezierPoint {
/// The index of the point along the path.
public let index: Int
/// The total number of B-Spline control points in the path.
public let pointCount: Int
/// The location of the cubic uniform B-Spline control point.
public let location: CGPoint
/// The index of the Bézier segment the point originates from, not including `move to` elements.
public let bezierSegmentIndex: Int
}PKStrokePath.idpublic var id: UUID { get }The unique identity of the stroke path.
Warning: Using multiple stroke paths with identical IDs but different control points
will result in undefined rendering behavior. Ensure each stroke path has a unique identifier.
PKStrokePath.IDpublic typealias ID = UUIDA type representing the stable identity of the entity associated with an instance.
PKStrokePath.initpublic init(bezierPath: CGPath, creationDate: Date, pointProvider: (_ convertedPoint: PKStrokePath.ConvertedBezierPoint) -> PKStrokePoint)Creates a stroke path recreating the specified Bézier path as a cubic uniform B-Spline.
The count of control points of the generated spline is not guaranteed to be a specific value except when the provided path is the output of bezierRepresentation->CGPath, where it will match the original curve.
The output B-Spline will have continuous curvature and 0 curvature at the endpoints. In cases where the B-Spline cannot fully recreate the Bézier path, it will be an approximation. For example, if the given Bézier path includes line to elements, these will produce straight line segments in the resulting B-Spline, but if a line to element is adjacent to a curve to element, the resulting curve may not match the original.
Warning: For a Bézier path with multiple subpaths, only the first will be converted.
Parameters
bezierPathcreationDatepointProviderPKStrokePoints of the path with specific values.PKStrokePath.initpublic init<T>(controlPoints: T, creationDate: Date, id: UUID) where T : Sequence, T.Element == PKStrokePointCreates a stroke path with the specified cubic B-spline control points and a unique identifier.
Warning: Using multiple stroke paths with identical IDs but different control points
will result in undefined rendering behavior. Ensure each stroke path has a unique identifier.
Parameters
controlPointscreationDateidPKStrokePath.subscriptpublic subscript(range: ClosedRange<CGFloat>) -> PKStrokePath { get }Returns a copy of the path containing the control points in the specified parametric range.
Important: This subscript returns a new stroke path with points always starting at index zero. This differs from the Range<Int> subscript, which returns a Slice with points at their original index.
Parameters
rangeReturnsA new stroke path containing the portion within the specified parametric range.
PKStrokePoint.initpublic init(location: CGPoint, timeOffset: TimeInterval, size: CGSize, opacity: CGFloat, force: CGFloat, azimuth: CGFloat, altitude: CGFloat, secondaryScale: CGFloat, threshold: CGFloat, lateralJitter: CGFloat)Creates a stroke point with the specified properties, including lateral jitter.
PKStrokePoint.lateralJitterpublic var lateralJitter: CGFloat { get }The amount of lateral particle jitter at the stroke edge for supported inks.
Lateral jitter applies only to some inks, such as .pencil.
No APIs match your filter.