
-
Découvrez PaperKit
Découvrez comment intégrer PaperKit à vos apps iOS, iPadOS, macOS et visionOS. Nous verrons comment intégrer de manière transparente le dessin PencilKit avec des fonctionnalités de balisage telles que des formes et des images, et comment personnaliser l'interface utilisateur. Découvrez les bonnes pratiques en matière de compatibilité ascendante et découvrez des options de personnalisation avancées pour créer des expériences de balisage vraiment uniques dans vos apps.
Chapitres
- 0:00 - Introduction
- 1:36 - Apprendre à connaître PaperKit
- 3:35 - Débuter avec PaperKit
- 8:37 - Personnalisation de l’ensemble des fonctionnalités
Ressources
Vidéos connexes
WWDC24
WWDC20
-
Rechercher dans cette vidéo…
Bienvenue, je suis Andreea, ingénieure dans l’équipe Pencil et Paper, et je suis ravie de vous présenter PaperKit. PaperKit est le framework Apple qui alimente l’expérience d’annotation unifiée sur l’ensemble du système. Il est utilisé dans des apps comme Notes, Captures d’écran, Coup d’œil et Journal.
C’est le moyen le plus simple d’ajouter des annotations à une app. PaperKit offre un canevas où vous pouvez dessiner et ajouter divers éléments d’annotation, comme des formes, des images, des zones de texte, etc. La prise en charge du dessin et des annotations fait de PaperKit un atout majeur pour offrir une expérience d’annotation complète dans toute app.
Désormais dans macOS Tahoe, PaperKit offre la même expérience riche, permettant aux éléments de dessin et d’annotation de fonctionner parfaitement sur toutes les apps macOS, comme la nouvelle app Journal.
Je vais d’abord présenter les principales fonctionnalités de PaperKit et expliquer ses composants essentiels.
Ensuite, je vais vous montrer comment intégrer PaperKit en quelques étapes.
Enfin, je vais vous expliquer comment personnaliser l’expérience PaperKit selon les besoins de votre app.
Je vais commencer par présenter les fonctionnalités avec une démo. J’ai créé une app pour suivre toutes mes recettes et y apporter des modifications grâce aux annotations. J’ai déjà écrit la recette de mes biscuits traditionnels préférés, que je fais depuis l’âge de 7 ans, et je l’ai notée avec des étoiles. Je vais aussi ajouter une image des biscuits. Il me suffit d’ouvrir l’app Fichiers et de faire glisser une image dans ma recette.
Je la repositionne pour qu’elle soit bien présentée !
Je vais aussi surligner « noix moulues », car c’est l’ingrédient principal.
Maintenant que vous connaissez PaperKit, voyons ses trois composants clés. Le premier, PaperMarkupViewController, est le contrôleur qui permet de créer et d’afficher interactivement les dessins et annotations PaperKit.
Le deuxième est le conteneur de données, appelé PaperMarkup. Il gère l’enregistrement, le chargement et le rendu des annotations PaperKit, ainsi que des dessins PencilKit.
Le troisième est un nouveau menu d’insertion qui permet d’annoter des éléments dans le canevas. Sur iOS, iPadOS et visionOS 26, cela s’appelle un MarkupEditViewController.
Sur macOS, une autre option est la nouvelle barre d’outils MarkupToolbarViewController, qui inclut des outils de dessin et des boutons d’annotation.
Il est facile de démarrer avec PaperKit dans votre app. Je vais d’abord expliquer son intégration à mon app de recettes sur iOS, puis détailler les étapes pour macOS.
J’ai commencé par créer une sous-classe de UIViewController. Dans la méthode viewDidLoad, j’ai créé un conteneur de données d’annotation en l’adaptant aux dimensions de la vue pour garantir une mise en page et un rendu corrects. Ensuite, j’ai créé un contrôleur d’annotation configuré avec l’ensemble des dernières fonctionnalités proposées par PaperKit.
Je l’ai ajouté à la hiérarchie de vues en utilisant le processus standard d’intégration de contrôleur.
Pour créer un sélecteur d’outils, j’ai initialisé un sélecteur PencilKit et enregistré le contrôleur d’annotation comme observateur, afin qu’il réagisse dynamiquement aux changements d’état du sélecteur.
Pour afficher le sélecteur d’outils dans mon app, je l’ai assigné à la propriété activeToolPicker de l’état de réponse PencilKit. Il s’agit d’une nouvelle API disponible sur UIResponder qui contrôle la visibilité du sélecteur d’outils pour le répondeur actif. En configurant la propriété toolPickerVisibility, je peux garder le sélecteur actif tout en contrôlant sa visibilité à l’écran. Ainsi, le sélecteur reste caché mais fonctionnel, réactif au double toucher et au pincement, permettant à toute app d’offrir l’expérience du mini sélecteur. Pour en savoir plus sur la configuration du sélecteur d’outils, consultez Introducing PencilKit (WWDC19) et Squeeze the most out of Apple Pencil (WWDC24). Une fois le sélecteur d’outils configuré, j’ai configuré l’élément accessoire en tant que bouton. Lorsqu’il est activé, il déclenche une fonction qui affiche le menu d’insertion.
J’ai initialisé le contrôleur d’insertion avec le même ensemble de fonctionnalités que le contrôleur d’annotation.
J’ai ensuite défini le délégué du contrôleur sur le contrôleur d’annotation, configuré son affichage en pop-up, puis ancré cette pop-up au bouton ajouté dans le sélecteur d’outils pour un positionnement précis.
Enfin, j’ai présenté le menu d’insertion en mode modale.
Et sur macOS, c’est tout aussi facile à mettre en place.
Configurer le modèle et le contrôleur d’annotation se fait de la même manière.
Sur macOS, la seule différence, c’est qu’on peut créer une barre d’outils pour présenter l’UI d’insertion. Définissez le contrôleur d’annotation comme délégué de la barre d’outils, puis intégrez celle-ci à la vue avec le processus standard d’un NSViewController.
Une fois la configuration terminée, prenez un moment pour examiner les éléments essentiels à l’amélioration de l’expérience utilisateur.
PaperKit s’intègre parfaitement dans un environnement SwiftUI. Les composants sont encapsulés dans un UIViewControllerRepresentable, qui est ensuite incorporé directement dans le corps d’une vue SwiftUI. On peut ainsi intégrer des composants UIKit dans une mise en page SwiftUI, en conservant la compatibilité entre les deux frameworks. Pour en savoir plus sur les contrôleurs de vue dans un environnement SwiftUI regardez la vidéo What’s New in SwiftUI de la WWDC20.
Le contrôleur d’annotation dispose d’un délégué permettant de personnaliser la gestion des rappels. Je peux implémenter la méthode du délégué des modifications d’annotations pour enregistrer les modifications du modèle d’annotation. Le contrôleur d’annotation est aussi conforme au protocole Observable, ce qui permet de gérer l’état et les mises à jour sans passer par un délégué.
Pour assurer la compatibilité future, vérifiez toujours la version du contenu lors du chargement depuis le disque. Il existe deux approches courantes pour gérer les incompatibilités de version : afficher une alerte pour informer qu’une mise à jour est nécessaire, ou bien présenter une vignette prérendue de l’annotation.
PaperKit fournit des outils qui simplifient grandement la compatibilité ascendante. Créez d’abord un CGContext pour y générer la vignette.
Utilisez la fonction draw du modèle d’annotation pour générer une vignette, puis enregistrez-la avec les données du modèle.
Afficher une vignette en cas d’écart de version est la meilleure approche. C’est exactement ce que font des apps comme Notes.
Après avoir couvert les bases de PaperKit sur iOS et macOS, voyons comment personnaliser votre app pour offrir l’expérience d’annotation que vous souhaitez. L’ensemble des fonctionnalités d’annotation disponibles dans PaperKit est appelé FeatureSet. Il spécifie les capacités et les outils mis à disposition des contrôleurs d’annotation et d’insertion.
FeatureSet.latest fournit l’ensemble des fonctionnalités d’annotation disponibles dans PaperKit. C’est idéal pour commencer, car vous profiterez automatiquement des ajouts futurs au framework.
Pour personnaliser votre expérience d’annotation, vous pouvez utiliser les fonctions remove et insert. Vous avez ainsi la main sur l’ensemble des outils et des interactions proposés dans votre app.
Pour activer le HDR dans votre annotation, il suffit d’attribuer à la propriété colorMaximumLinearExposure du FeatureSet une valeur supérieure à 1. Pour une annotation en SDR, utilisez 1. Pour les encres HDR, appliquez aussi cette propriété au sélecteur d’outils. Pour mon app, la valeur 4 a produit l’effet HDR souhaité.
La valeur définie pour colorMaximumLinearExposure sera automatiquement adaptée à la plage HDR que l’écran de votre appareil peut gérer. Ou utilisez tout simplement la valeur supportée par l’écran, accessible via UIScreen ou NSScreen.
Avec le dernier FeatureSet et le HDR activé, votre app profitera des dernières fonctionnalités et expériences proposées. Par exemple, un nouvel outil de calligraphie appelé Reed, introduit dans PencilKit, qui offre un rendu superbe en HDR.
Une fois votre ensemble de fonctionnalités personnalisé, appliquez-le au contrôleur d’annotation et au contrôleur d’insertion pour assurer une expérience cohérente dans toute l’app.
La propriété contentView du contrôleur d’annotation est également personnalisable avec n’importe quelle UIView. Par exemple, je peux utiliser le modèle comme élément fixe dans mon app. L’ensemble des annotations et dessins s’affichera par-dessus. Grâce à un FeatureSet personnalisé, une vue d’arrière-plan configurée et des ajustements ciblés, votre app offrira une expérience d’annotation complète, à la fois puissante et adaptée à vos besoins.
Et ensuite ? Adoptez l’expérience d’annotation d’Apple, personnalisez votre FeatureSet avec vos propres outils et encres, définissez un arrière-plan personnalisé et ajoutez la prise en charge du HDR à vos annotations.
Que vous conceviez un outil de prise de notes simple ou une toile créative élaborée, PaperKit vous fournit les bons ingrédients pour une expérience parfaite. J’ai hâte de voir ce que vous allez créer avec PaperKit.
Merci de votre attention !
-
-
3:47 - Adopt PaperKit in iOS
// Adopt PaperKit in iOS override func viewDidLoad() { super.viewDidLoad() let markupModel = PaperMarkup(bounds: view.bounds) let paperViewController = PaperMarkupViewController(markup: markupModel, supportedFeatureSet: .latest) view.addSubview(paperViewController.view) addChild(paperViewController) paperViewController.didMove(toParent: self) becomeFirstResponder() let toolPicker = PKToolPicker() toolPicker.addObserver(paperViewController) pencilKitResponderState.activeToolPicker = toolPicker pencilKitResponderState.toolPickerVisibility = .visible toolPicker.accessoryItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(plusButtonPressed(_:))) } @objc func plusButtonPressed(_ button: UIBarButtonItem) { let markupEditViewController = MarkupEditViewController(supportedFeatureSet: .latest) markupEditViewController.delegate = paperViewController markupEditViewController.modalPresentationStyle = .popover markupEditViewController.popoverPresentationController?.barButtonItem = button present(markupEditViewController, animated: true) }
-
6:11 - Adopt PaperKit in macOS
// Adopt PaperKit in macOS override func viewDidLoad() { super.viewDidLoad() let markupModel = PaperMarkup(bounds: view.bounds) let paperViewController = PaperMarkupViewController(markup: markupModel, supportedFeatureSet: .latest) view.addSubview(paperViewController.view) addChild(paperViewController) // Create toolbar for macOS let toolbarViewController = MarkupToolbarViewController(supportedFeatureSet: .latest) toolbarViewController.delegate = paperViewController view.addSubview(toolbarViewController.view) // Set layout setupLayoutConstraints() }
-
7:18 - Auto-save markup changes
// Auto-save markup changes func paperMarkupViewControllerDidChangeMarkup(_ paperMarkupViewController: PaperMarkupViewController) { let markupModel = paperMarkupViewController.markup Task { // Create a data blob and save it let data = try await markupModel.dataRepresentation() try data.write(toFile: paperKitDataURL) } }
-
8:02 - Thumbnail for forward compatibility
// Thumbnail for forward compatibility func updateThumbnail(_ markupModel: PaperMarkup) async throws { // Set up CGContext to render thumbnail in let thumbnailSize = CGSize(width: 200, height: 200) let context = makeCGContext(size: thumbnailSize) context.setFillColor(gray: 1, alpha: 1) context.fill(renderer.format.bounds) // Render the PaperKit markup await markupModel.draw(in: context, frame: CGRect(origin: .zero, size: thumbnailSize)) thumbnail = context.makeImage() }
-
9:02 - Customized markup FeatureSet
// Customized markup FeatureSet var featureSet: FeatureSet = .latest featureSet.remove(.text) featureSet.insert(.stickers) // HDR support featureSet.colorMaximumLinearExposure = 4 toolPicker.colorMaximumLinearExposure = 4 let paperViewController = PaperMarkupViewController(supportedFeatureSet: featureSet) let markupEditViewController = MarkupEditViewController(supportedFeatureSet: featureSet)
-
10:50 - Custom background on markup controller
// Custom background on markup controller let template = UIImage(named: "MyTemplate.jpg") let templateView = UIImageView(image: template) paperViewController.contentView = templateView
-
-
- 0:00 - Introduction
Grâce à PaperKit, vous pouvez créer des expériences de balisage riches dans diverses apps iOS et macOS, notamment Notes, Captures d’écran, QuickLook et l’app Journal. Le framework fournit un canevas sur lequel il est possible de dessiner et d’ajouter des formes, des images, des champs de saisie de texte, etc. PaperKit simplifie l’intégration de fonctionnalités de balisage dans n’importe quelle app, offrant ainsi une expérience utilisateur fluide.
- 1:36 - Apprendre à connaître PaperKit
L’app prise en exemple est un outil de gestion de recettes qui permet aux utilisateurs de créer, mettre à jour et annoter des recettes à l’aide de balises. L’app comprend un contrôleur de balisage, un conteneur de modèle de données et un menu ou une barre d’outils d’insertion (selon le système d’exploitation) pour faciliter l’annotation. La démo présente ces fonctionnalités avec l’ajout d’une image, la mise en évidence des ingrédients et l’évaluation d’une recette traditionnelle de biscuits roumains.
- 3:35 - Débuter avec PaperKit
Pour intégrer PaperKit dans une app iOS, créez une sous-classe UIViewController et initialisez un conteneur de modèle de données de balisage et un contrôleur. Ensuite, configurez un sélecteur d’outils PencilKit et un contrôleur de menu d’insertion qui s’affichera sous forme de fenêtre contextuelle lorsqu’il sera déclenché par un bouton accessoire. Vous pouvez également intégrer PaperKit de manière transparente dans un environnement SwiftUI. Le contrôleur de balisage comprend un délégué pour la gestion personnalisée des rappels et est conforme à Observable pour la gestion de l’état. Lorsque vous chargez des données à partir d’un disque, il est essentiel de vérifier la version du contenu pour garantir la compatibilité ascendante. PaperKit fournit des outils permettant de générer des miniatures pour le pré-rendu, en cas d’incompatibilité entre les versions.
- 8:37 - Personnalisation de l’ensemble des fonctionnalités
Le FeatureSet de PaperKit définit les fonctionnalités de balisage disponibles dans une app. Vous pouvez commencer par FeatureSet.latest pour inclure toutes les dernières fonctionnalités. Pour personnaliser l’app, vous pouvez supprimer ou insérer des outils et des interactions à l’aide des fonctions fournies. Pour activer la prise en charge HDR, définissez la propriété colorMaximumLinearExposure sur une valeur supérieure à 1, qui effectue une conversion tonale vers la plage HDR prise en charge par l’appareil. Cela améliore la qualité visuelle du balisage, en particulier lorsque vous utilisez de nouveaux outils tels que l’outil de calligraphie introduit dans PencilKit. Vous pouvez également personnaliser le contentView du contrôleur de balisage afin d’afficher n’importe quelle UIView, par exemple un modèle, et offrir ainsi un arrière-plan cohérent pour le balisage et le dessin.