Разрабатываем инструменты аннотирования документов в мобильном приложении. Мы реализуем не просто рисование поверх изображения, а полноценное встраивание аннотаций в структуру 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 недели. Точная оценка зависит от сложности кастомных аннотаций и требований к совместимости с другими приложениями. Получите консультацию бесплатно — напишите нам.







