Новый протокол Transferable был представлен на WWDC 2022 и призван значительно сократить усилия, необходимые с нашей стороны для копирования и вставки (Copy & Paste), a также для перетаскивание и “сброса” (Drag & Drop) данных внутри одного приложения или между разными приложениями.
Он пришел на замену классу NSItemProvider в iOS 16+, macOS 13+ (Ventura и новее), watchOS 9.0+ и tvOS 16+. Познакомиться с некоторыми аспектами применения протокола Transferable можно в постах Протокол Transferable меняет правила игры для Drag & Drop в SwiftUI и Протокол Transferable в SwiftUI — передача альтернативного контента с помощью ProxyRepresentation.
Однако попытка использовать протокол Transferable в демонстрационном примере EmojiArt из курса CS193P Стэнфордского университета, Весна 2021 (Лекция 9. Drag &Drop) и заменить класс class NSItemProvider на протокол Transferable привела к вопросу о том, как поддерживать “сброс” (Drop) нескольких Transferable ТИПов в один контейнер.
EmojiArt — это приложение, которое позволяет пользователю создавать определенную «картину», зайдя в интернет и выбрав там понравившееся изображение, которое можно «бросить» (Drop) на свой EmojiArtDocument в качестве красивого фонового изображения, а затем добавив к нему эмодзи (смайлики), создать красивое произведение искусства. Нам нравятся эмодзи. Эмодзи можно выбрать из любой тематической палитры, «бросать» их на создаваемую вами «картину» и передвигать их повсюду, изменять их размер. В нижней части экрана у нас целый спектр палитр эмодзи на разные темы.
В таком приложении мы должны предоставить пользователю возможность перетаскивать и «бросать» (Drag & Drop) строку String, URL-адрес или данные Data (например, данные изображения) в один и тот же ZStack. И до появления протокола Transferable это было сделано с помощью класса class NSItemProvider и View модификатора .onDrop:. . . . . . . . . . . . . .
Проблема в том, что при использовании нового протокола Transferable и нового View модификатора .dropDestination (for: action: isTargeted:); его параметр for не принимает несколько ТИПов «сбрасываемых» объектов одновременно, как это делает выше приведенный View модификатор .onDrop (of: [.plainText, .url, .image] …).