Canvas — интерактивный превью-редактор Xcode, который отображает SwiftUI View в реальном времени без запуска симулятора. Canvas обновляется автоматически при каждом изменении кода и поддерживает жесты, навигацию и тёмную тему. По данным Apple Developer Documentation (2026), Canvas использует отдельный процесс-рендерер PreviewProviderExtension, что позволяет редактировать код и сразу видеть результат без перекомпиляции всего проекта. Подробнее о SwiftUI читайте в материале по SwiftUI.
Главное
Canvas — встроенный превью-редактор Xcode, впервые представленный в Xcode 11 вместе со SwiftUI. Он расположен в правой панели редактора рядом с кодом и отображает live-превью текущей SwiftUI View. Canvas работает в режиме реального времени: каждое изменение в коде мгновенно отражается на превью без ручной перекомпиляции.
Архитектурно Canvas — это отдельный процесс (Preview Provider Extension), который запускается Xcode при открытии Canvas. Процесс загружает скомпилированный PreviewProvider, рендерит результат через Metal и отображает в панели редактора. Если PreviewProvider не реализован, Canvas показывает заглушку "Preview paused — No preview provider found".
Интерфейс Canvas включает панель инструментов с выбором устройства, ориентации, цветовой схемы и масштаба. Кнопки Live Preview, Selectable и Embed In Diagram переключают режимы взаимодействия. Canvas поддерживает split-view: можно открыть несколько Canvas для разных файлов в одной рабочей области.
| Элемент Canvas | Назначение |
|---|---|
| Device selector | Выбор устройства для превью (iPhone, iPad, Apple Watch) |
| Orientation toggle | Переключение портрет/ландшафт (iOS, iPadOS) |
| Color scheme | Светлая/тёмная тема |
| Dynamic Type slider | Масштаб шрифта для проверки accessibility |
| Live Preview | Интерактивный режим с поддержкой жестов |
| Selectable mode | Инспектирование элементов интерфейса |
Live Preview — ключевая возможность Canvas, которая делает превью интерактивным. В этом режиме Canvas рендерит View в отдельном процессе и передаёт жесты (тап, свайп, скролл) обратно в рантайм SwiftUI. Пользователь может нажимать кнопки, заполнять текстовые поля и тестировать навигацию без запуска симулятора.
SwiftUI обрабатывает жесты в Canvas через ту же систему событий, что и на реальном устройстве. Разница в производительности: Canvas использует software-рендеринг через Metal, тогда как симулятор — хост-графику. Это означает, что сложные анимации в Canvas могут работать медленнее или отличаться визуально.
Обновление Canvas происходит в три этапа. Сначала Xcode детектирует изменение файла и инкрементально компилирует только изменённый PreviewProvider. Затем новый бинарный модуль загружается в процесс PreviewProviderExtension. Наконец, SwiftUI пересоздаёт View и рендерит её через Metal. Весь цикл занимает 0.5–2 секунды в зависимости от сложности View.
struct TappableButton: View {
@State private var count = 0
var body: some View {
Button("Tapped \(count) times") {
count += 1
}
.buttonStyle(.borderedProminent)
}
}
struct TappableButton_Previews: PreviewProvider {
static var previews: some View {
TappableButton()
}
}
Интерактивность: при запуске Live Preview кнопка в Canvas работает как настоящая — счётчик увеличивается при каждом нажатии, анимация нажатия отображается. Это позволяет тестировать логику кнопок без симулятора.
Базовые настройки Canvas доступны через меню Editor → Canvas или через кнопки на панели инструментов самого Canvas. Основные опции включают выбор устройства, ориентации, тёмной темы и масштаба Dynamic Type. Для постоянных настроек используйте PreviewProvider-модификаторы в коде.
Продвинутые настройки включают: Auto Activate Preview — автоматическое включение Canvas при открытии SwiftUI файла; Live Preview — режим с жестами; Draw Live Edges — отображение границ вью; Show Preview Sizes — размер области превью. Xcode сохраняет эти настройки переносно в файлах workspace/проекта.
Программная настройка даёт более точный контроль над Canvas. Модификаторы, применённые в previews, переопределяют настройки панели инструментов и сохраняются в коде — их видят все члены команды через git.
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
.previewDevice("iPhone 16 Pro")
.previewLayout(.device)
.preferredColorScheme(.dark)
.dynamicTypeSize(.xxxLarge)
.previewDisplayName("Dark + XL Text")
}
}
previewLayout с .device отображает полный экран устройства, а .sizeThatFits — компактное превью с размером, подстроенным под содержимое. Для виджетов и мелких компонентов используйте .sizeThatFits — это экономит место в редакторе.
Пример 1: проверка адаптивности. Используйте ForEach с несколькими устройствами и цветовыми схемами, чтобы убедиться, что интерфейс одинаково хорошо выглядит на всех экранах. Canvas обновляет все превью одновременно, позволяя заметить layout issues до запуска симулятора.
Пример 2: превью с данными. Для View, отображающих динамический контент (списки, профили, карточки), создавайте несколько экземпляров с разными данными в previews. Это быстрее, чем переключаться между экранами в симуляторе и вводить данные.
Группа превью через Group или ForEach позволяет отобразить все состояния компонента на одной панели. Для списка это особенно удобно: пустой список, загрузка, ошибка и заполненный список видны одновременно.
struct LoadingStateView: View {
let state: LoadingState
var body: some View {
switch state {
case .loading:
ProgressView()
case .loaded(let items):
List(items, id: \.self) { Text($0) }
case .error(let message):
Text(message).foregroundColor(.red)
}
}
}
struct LoadingStateView_Previews: PreviewProvider {
static var previews: some View {
Group {
LoadingStateView(state: .loading)
.previewDisplayName("Loading")
LoadingStateView(state: .loaded(["Item 1", "Item 2"]))
.previewDisplayName("Loaded")
LoadingStateView(state: .error("Failed to load"))
.previewDisplayName("Error")
}
}
}
Canvas и Simulator дополняют друг друга, а не заменяют. Canvas идеален для быстрой итерации при вёрстке: редактирование кода с немедленной обратной связью. Simulator необходим для финальной проверки: реальная производительность, кастомные жесты, системные алерты и интеграция с аппаратными функциями (камера, датчики).
По данным WWDC 2024, Apple позиционирует Canvas как инструмент для разработчика на ранних этапах, а Simulator — для этапа интеграционного тестирования. 60% времени разработки UI рекомендуется проводить в Canvas, 40% — проверять на симуляторе или устройстве.
| Характеристика | Canvas | Simulator |
|---|---|---|
| Скорость обновления | 0.5–2 сек (инкрементальная) | 10–60 сек (полная сборка) |
| Жесты | Базовые (тап, скролл) | Все (pinch, rotate, 3D Touch) |
| Камера/гироскоп | Не поддерживается | Симулируется |
| Анимации | Ограниченно | Полностью |
| Push-уведомления | Не поддерживается | Поддерживается |
| Сеть | Через процесс Xcode | Полноценный сетевой стек |
Рекомендация: верстайте в Canvas, тестируйте на симуляторе. Используйте Live Preview для жестовой логики кнопок и навигации, но финальную проверку анимаций, сетевых запросов и hardware-функций проводите на симуляторе или реальном устройстве.
Совет 1: используйте Selectable mode. В режиме Selectable (иконка курсора) можно кликнуть на любой элемент превью и увидеть его иерархию, модификаторы и фрейм в инспекторе. Это полезно для отладки layout: вы мгновенно видите padding, offset и размер элемента без принтов.
Совет 2: Embed In Diagram. Canvas умеет группировать элементы: select две и более View, нажмите Embed In Diagram — Canvas создаст VStack/HStack/ZStack и перестроит код автоматически. Это ускоряет создание сложной иерархии без ручного набора скобок.
Совет 3: очистка Canvas Preview Cache. Если Canvas перестал обновляться, очистите Product → Preview Cache. Xcode удалит закэшированные бинарники PreviewProvider и перестроит их с нуля. Это решает 90% проблем с зависшим Canvas.
Медленный Canvas обычно вызван избыточным количеством превью. Для сложных View используйте только одно превью, а не группу из 6–8. Выключайте Live Preview для View без жестов — статический режим рендерится быстрее. Убедитесь, что PreviewProvider использует моки, а не реальные сетевые запросы.
// Quick debug: minimal preview
struct ComplexView_Previews: PreviewProvider {
static var previews: some View {
ComplexView()
.previewLayout(.sizeThatFits) // compact mode
}
}
previewLayout(.sizeThatFits) — самый быстрый режим Canvas, так как рендерится только содержимое View без рамок устройства. Используйте его для повседневной вёрстки, включайте .device только для финальной проверки.
Часто задаваемые вопросы
Самая частая причина — отсутствие PreviewProvider для текущей View. Canvas требует реализации протокола PreviewProvider с возвратом View в свойстве previews. Другие причины: ошибка компиляции в коде, проблемы с DerivedData или процесс PreviewProviderExtension не запустился.
Да, Xcode поддерживает отладку превью через Product → Preview → Debug Preview. После активации breakpoint в коде View сработает при рендеринге Canvas. Это позволяет анализировать runtime-значения переменных и проверять логику отображения.
Canvas поддерживает UIKit-компоненты через UIViewRepresentable и UIViewControllerRepresentable. Однако некоторые компоненты не рендерятся: MapKit, WebView, видео через AVPlayer, кастомные Metal/GLKit вью. Canvas не эмулирует аппаратные возможности, поэтому камера и датчики недоступны.
Уменьшите количество превью в Group (макс 3–4), используйте previewLayout(.sizeThatFits) вместо .device, отключите Live Preview для View без жестов. Очистите Product → Preview Cache. Убедитесь, что PreviewProvider не выполняет сетевые запросы — используйте мок-данные.
Canvas не влияет на размер релизного IPA — PreviewProvider-код компилируется только в Debug-конфигурации. В процессе разработки Canvas добавляет до 100–200 МБ кэша в DerivedData, который автоматически управляется Xcode. Регулярная очистка DerivedData освобождает место.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также