2024 App ServicesSwiftUI & UI Frameworks
WWDC24 · 15 min · App Services / SwiftUI & UI Frameworks
Squeeze the most out of Apple Pencil
New in iOS 18, iPadOS 18, and visionOS 2, the PencilKit tool picker gains the ability to have completely custom tools, with custom attributes. Learn how to express your custom drawing experience in the tool picker using the same great tool picking experience available across the system. Discover how to access the new features of the Apple Pencil Pro, including roll angle, the squeeze gesture, and haptic feedback.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 4 snippets
Respond to squeeze in UIKit
class MyViewController: UIViewController, UIPencilInteractionDelegate {
func pencilInteraction(_ interaction: UIPencilInteraction,
didReceiveSqueeze squeeze: UIPencilInteraction.Squeeze) {
if UIPencilInteraction.preferredSqueezeAction == .showContextualPalette &&
squeeze.phase == .ended {
let anchorPoint = squeeze.hoverPose?.location ?? myDefaultLocation
presentMyContextualPaletteAtPosition(anchorPoint)
}
}
} Respond to squeeze in SwiftUI
(\.preferredPencilSqueezeAction) var preferredAction
var contextualPalettePresented = false
var contextualPaletteAnchor = MyPaletteAnchor.default
var body: some View {
MyView()
.onPencilSqueeze { phase in
if preferredAction == .showContextualPalette, case let .ended(value) = phase {
if let anchorPoint = value.hoverPose?.anchor {
contextualPaletteAnchor = .point(anchorPoint)
}
contextualPalettePresented = true
}
}
} Provide canvas feedback in UIKit
class MyViewController: UIViewController {
var feedbackGenerator: UICanvasFeedbackGenerator
override func viewDidLoad() {
super.viewDidLoad()
feedbackGenerator = UICanvasFeedbackGenerator(view: view)
}
func dragAlignedToGuide(_ sender: MyDragGesture) {
feedbackGenerator.alignmentOccurred(at: sender.location(in: view))
}
func snappedToShape(_ sender: MyDrawGesture) {
feedbackGenerator.pathCompleted(at: sender.location(in: view))
}
} Provide canvas feedback in SwiftUI
var dragAlignedToGuide = 0
var snappedToShape = 0
var body: some View {
MyView()
.sensoryFeedback(.alignment, trigger: dragAlignedToGuide)
.sensoryFeedback(.pathComplete, trigger: snappedToShape)
} Resources
Related sessions
-
35 min -
16 min -
14 min