Розробляємо інструменти анотування документів у мобільному додатку. Ми реалізуємо не просто малювання поверх зображення, а повноцінне вбудовування анотацій у структуру PDF-файлу. Анотації масштабуються без втрати позицій при зміні зуму і зберігаються так, щоб їх міг прочитати будь-який сумісний рідер — Adobe Acrobat, Foxit, Preview. Нижче — технічні деталі реалізації для iOS, Android та Flutter, засновані на нашому досвіді (10+ років у мобільній розробці, 50+ проектів з анотуванням).
Наприклад, в одному з проектів для юридичної платформи ми реалізували підтримку 12 типів анотацій з синхронізацією через WebSocket. Це дозволило кільком юристам одночасно редагувати один документ з iPad та Android-планшетів, економлячи до 40% часу на узгодженнях.
Типи анотацій та їх технічна реалізація
Стандарт PDF (ISO 32000) визначає типи анотацій: /Text (стікер), /Highlight, /Underline, /StrikeOut, /Ink (вільне малювання), /FreeText, /Square, /Circle, /Stamp. Реалізовувати їх як оверлей поверх UIImageView — антипатерн: при перерендері сторінки позиції збиваються. Анотації повинні зберігатися в координатах PDF-простору (точки PDF, не пікселі екрану). Ми використовуємо підхід прив'язки анотацій до сторінки через стандартні API.
iOS. PDFKit — нативний фреймворк з PDFAnnotation. Створюємо анотацію:
let annotation = PDFAnnotation(bounds: bounds, forType: .highlight, withProperties: nil) annotation.color = UIColor.yellow.withAlphaComponent(0.5) page.addAnnotation(annotation) Координати bounds — в PDF-просторі сторінки. Перерахунок з touch-координат: pdfView.convert(touchPoint, to: page). Для Ink-анотації збираємо [UIBezierPath] і передаємо через annotation.paths. Збереження: document.write(to: url) — вбудує анотації в PDF-структуру.
Android. Нативного PDF-редактора немає. Популярні шляхи: PdfiumAndroid для рендерингу + власний Canvas-оверлей зі збереженням через iText7 або PDFBox. iText7 (Community, AGPL) вміє додавати анотації в існуючий PDF через PdfAnnotation. Комерційний варіант — PdfTron/Apryse SDK: повний стандарт ISO 32000, працює офлайн.
Flutter. syncfusion_flutter_pdfviewer + syncfusion_flutter_pdf (платні для production) або pdfx для рендерингу + ручна реалізація через CustomPainter. Безкоштовного повного рішення немає — або платний SDK, або нативний plugin.
Порівняння фреймворків для анотування
| Платформа | Фреймворк / SDK | Складність реалізації | Сумісність зі стандартом | Ліцензія |
|---|---|---|---|---|
| iOS | PDFKit (нативний) | Низька | Повна (ISO 32000) | Вбудовано в ОС |
| Android | iText7 + Canvas | Висока | Часткова (AGPL) | AGPL / комерційна |
| Android | PdfTron/Apryse | Середня | Повна | Комерційна |
| Flutter | syncfusion_flutter_pdf | Середня | Повна | Комерційна (тріал) |
| Flutter | pdfx + CustomPainter | Висока | Обмежена | Безкоштовно |
Який фреймворк вибрати для анотування на iOS?
Вибір між PDFKit та CGPDFDocument + кастомний рендеринг. PDFKit в 3 рази швидший в розробці та підтримує всі стандартні анотації з коробки. Ми рекомендуємо PDFKit для більшості завдань, а CGPDFDocument — тільки коли потрібен нестандартний рендеринг (наприклад, накладання своїх шарів).
Чому Ink-анотації складніші за highlight?
Вільне малювання пальцем працює нормально. Стилус (Apple Pencil, Samsung S Pen) — інша історія. На iOS Apple Pencil дає UITouch.force та UITouch.azimuthAngle. Для realistic drawing: змінюємо товщину лінії від сили натискання, застосовуємо згладжування через алгоритм Catmull-Rom spline між точками. Без згладжування лінія при швидкому русі виглядає кутастою — UITouch не встигає передати всі проміжні точки.
Оптимізація рендерингу: не перемальовуємо всю сторінку на кожен touchesMoved. Використовуємо setNeedsDisplayInRect з bounding box останнього відрізка. На складних документах повна перемальовка падає FPS до 20–30, incremental — тримає 60.
Підсвітка тексту (Highlight) поверх PDF
Для коректного highlight потрібно знати координати слів у PDF. PDFPage.selectionForRange та PDFSelection дають PDFPage.characterBounds(at:) для кожного символу. Highlight малюємо не прямокутником всієї виділеної області, а набором прямокутників по рядках — інакше на багаторядковому виділенні виходить один широкий блок замість акуратних смужок. Ми використовуємо цей підхід у всіх проектах.
Часті помилки при реалізації анотацій
- Збереження анотацій в базі даних замість вбудовування в PDF — після експорту вони втрачаються.
- Використання фіксованих піксельних координат — при зміні масштабу анотації з'їжджають.
- Відсутність обробки повороту сторінки — на пристроях з орієнтацією портрет/ландшафт анотації можуть відображатися некоректно.
- Ігнорування відступів та обрізки (crop box) PDF — анотації можуть потрапити за межі видимої області.
Експорт і сумісність
Після редагування користувач очікує отримати PDF, який відкриється в будь-якому рідері. PDFKit.document.write(to:) на iOS це гарантує. На Android iText7 записує стандартні анотації. Проблема виникає з custom stamps та SVG-зображеннями — їх потрібно растеризувати перед вбудовуванням. Шаринг: UIActivityViewController на iOS, FileProvider + Intent.ACTION_SEND на Android.
Що входить у роботу
При замовленні реалізації анотування під ключ ви отримуєте:
- Вихідний код з підтримкою виділення тексту, нотаток, вільного малювання та інших типів анотацій;
- Інтеграцію з App Store / Google Play (code signing, provisioning profile);
- Тестування на реальних пристроях (мінімум 5 моделей);
- Документацію по API та процесу збірки;
- Підтримку протягом 3 місяців після здачі.
Ми також допомагаємо налаштувати push-повідомлення (APNs/FCM), deep linking та in-app purchase для преміум-функцій. Гарантуємо сумісність з актуальними версіями iOS та Android. Оцінимо ваш проект за 2 робочі дні — зв'яжіться з нами для консультації.
Строки орієнтовно
Базовий набір (highlight, underline, freetext, ink) на одну платформу — 3–4 дні. Повний редактор з підтримкою стилуса, синхронізацією між пристроями та хмарним сховищем — 2–3 тижні. Точна оцінка залежить від складності кастомних анотацій та вимог до сумісності. Отримайте консультацію безкоштовно — напишіть нам.







