Добавить объявление

Контекстные меню с превью в SwiftUI: показываем детали до действия

Контекстные меню в SwiftUI это мощный инструмент для скрытия дополнительных действий и функций. Однако они часто страдают от недостатка контекста: пользователь не всегда понимает, к чему именно относится действие, пока не нажмет на него. Начиная с iOS 16, SwiftUI предлагает решение этой проблемы с помощью модификатора preview, который позволяет показывать детальную информацию прямо в меню, прежде чем пользователь сделает выбор.

Базовый пример - уточнение действия:


Рассмотрим сценарий с просмотром документа. Без preview пользователь видит только действия, но не понимает, какой именно документ будет затронут:

DocumentCard(document: report)
.contextMenu {
Button("Переименовать", systemImage: "pencil") {
rename()
}

Button("Создать копию", systemImage: "doc.on.doc") {
duplicate()
}

Button("Удалить", systemImage: "trash", role: .destructive) {
delete()
}
}

С добавлением preview меню становится самодостаточным:

DocumentCard(document: report)
.contextMenu {
Button("Переименовать", systemImage: "pencil") {
rename()
}

Button("Создать копию", systemImage: "doc.on.doc") {
duplicate()
}

Button("Удалить", systemImage: "trash", role: .destructive) {
delete()
}
} preview: {
// Preview показывает, с каким документом работаем
VStack(alignment: .leading, spacing: 8) {
Text(report.title)
.font(.headline)

HStack {
Label("\(report.pageCount) стр.", systemImage: "doc.text")
Label(report.formattedDate, systemImage: "calendar")
}
.font(.caption)
.foregroundStyle(.secondary)

if let previewText = report.preview {
Text(previewText)
.font(.caption)
.lineLimit(3)
.foregroundStyle(.secondary)
}
}
.padding()
.frame(width: 300)
}

Расширенный сценарий - интерактивный preview:


Модификатор preview поддерживает не только статический контент, но и интерактивные элементы, что открывает дополнительные возможности:

Image(uiImage: selectedPhoto)
.resizable()
.aspectRatio(contentMode: .fit)
.contextMenu {
Button("Редактировать", systemImage: "slider.horizontal.3") {
editPhoto()
}
Button("Поделиться", systemImage: "square.and.arrow.up") {
sharePhoto()
}
Button("Удалить", systemImage: "trash", role: .destructive) {
deletePhoto()
}
} preview: {
// Preview с возможностью масштабирования
ZoomableImageView(image: selectedPhoto)
.frame(height: 300)
.cornerRadius(12)
}

Важные детали:


  • Preview работает только в контекстных меню, вызванных долгим нажатием.

  • Размер и layout preview можно гибко настраивать.

  • Preview поддерживает анимации и переходы внутри себя.

  • Может содержать любые SwiftUI вью, включая списки, сетки и интерактивные элементы.

Оптимизация производительности:


Поскольку preview рендерится в момент появления меню, стоит избегать тяжелых операций в его инициализации. Для динамических данных лучше использовать отложенную загрузку или кэширование.

Вывод:


Модификатор preview для контекстных меню - это не просто косметическое улучшение, а фундаментальное изменение подхода к проектированию контекстных действий. Он позволяет превратить меню из простого списка команд в информативный интерфейсный элемент, который показывает пользователю ровно ту информацию, которая нужна для принятия осознанного решения.
15.12.2025 14 529