Перетаскивание в Xamarin.iOS
Реализация перетаскивания для iOS 11
iOS 11 включает поддержку перетаскивания для копирования данных между приложениями на iPad. Пользователи могут выбирать и перетаскивать все типы содержимого из приложений, расположенных параллельно или перетаскивая значок приложения, который активирует открытие приложения и разрешение удаления данных:
Примечание.
До iOS 15 перетаскивание доступно только в одном приложении на i Телефон. В iOS 15 представлено перетаскивание и перетаскивание между приложениями.
Рассмотрите возможность поддержки операций перетаскивания в любом месте, где можно создать или изменить содержимое:
- Элементы управления текстом поддерживают перетаскивание для всех приложений, созданных в iOS 11, без дополнительной работы.
- Представления таблиц и представления коллекции включают улучшения в iOS 11, которые упрощают добавление поведения перетаскивания и перетаскивания.
- Любое другое представление можно сделать для поддержки перетаскивания с дополнительной настройкой.
При добавлении поддержки перетаскивания в приложения можно предоставить различные уровни точности содержимого; Например, можно указать форматированный текст и версию данных обычного текста, чтобы принимающее приложение могло выбрать, что лучше всего подходит в целевой объект перетаскивания. Кроме того, можно настроить визуализацию перетаскивания, а также включить перетаскивание нескольких элементов одновременно.
Перетаскивание с текстовыми элементами управления
UITextView
и UITextField
автоматически поддерживает перетаскивание выделенного текста и удаление содержимого текста.
Перетаскивание с помощью UITableView
UITableView
имеет встроенную обработку для взаимодействия перетаскивания с строками таблиц, требуя только нескольких методов для включения поведения по умолчанию.
Существует два интерфейса:
IUITableViewDragDelegate
— пакеты сведений при инициировании перетаскивания в представлении таблицы.IUITableViewDropDelegate
— обрабатывает сведения при попытке и завершении удаления.
В примере этих двух интерфейсов реализованы в UITableViewController
классе вместе с делегатом и источником данных. Они назначаются в методе ViewDidLoad
:
this.TableView.DragDelegate = this;
this.TableView.DropDelegate = this;
Ниже описан минимальный обязательный код для этих двух интерфейсов.
Делегат перетаскивания представления таблиц
Единственный метод , необходимый для поддержки перетаскивания строки из представления GetItemsForBeginningDragSession
таблицы. Если пользователь начинает перетаскивать строку, этот метод будет вызван.
Ниже показана реализация. Он извлекает данные, связанные с перетаскиваемой строкой, кодирует его и настраивает NSItemProvider
способ обработки частью операции "drop" (например, может ли он обрабатывать тип данных, PlainText
в примере):
public UIDragItem[] GetItemsForBeginningDragSession (UITableView tableView,
IUIDragSession session, NSIndexPath indexPath)
{
// gets the 'information' to be dragged
var placeName = model.PlaceNames[indexPath.Row];
// convert to NSData representation
var data = NSData.FromString(placeName, NSStringEncoding.UTF8);
// create an NSItemProvider to describe the data
var itemProvider = new NSItemProvider();
itemProvider.RegisterDataRepresentation(UTType.PlainText,
NSItemProviderRepresentationVisibility.All,
(completion) =>
{
completion(data, null);
return null;
});
// wrap in a UIDragItem
return new UIDragItem[] { new UIDragItem(itemProvider) };
}
Существует множество необязательных методов делегата перетаскивания, которые можно реализовать для настройки поведения перетаскивания, например предоставления нескольких представлений данных, которые можно использовать в целевых приложениях (например, форматированный текст, обычный текст или векторные и растровые версии рисунка). Можно также предоставить пользовательские представления данных, которые будут использоваться при перетаскивании и удалении в одном приложении.
Делегат раскрывающегося представления таблицы
Методы делегата перетаскивания вызываются, когда операция перетаскивания возникает в представлении таблицы или завершается над ней. Необходимые методы определяют, разрешено ли удалять данные и какие действия выполняются при завершении удаления:
CanHandleDropSession
— Пока выполняется перетаскивание и потенциально удаляется в приложении, этот метод определяет, разрешено ли перетаскивание данных.DropSessionDidUpdate
— Пока выполняется перетаскивание, этот метод вызывается для определения предполагаемого действия. Сведения из представления таблицы, перетаскиваемого поверх, сеанс перетаскивания и возможный путь к индексу, можно использовать для определения поведения и визуальной обратной связи, предоставленной пользователю.PerformDrop
— Когда пользователь завершает удаление (поднимая пальцем), этот метод извлекает данные, перетаскиваемые и изменяет представление таблицы, чтобы добавить данные в новую строку (или строки).
CanHandleDropSession
CanHandleDropSession
указывает, может ли представление таблицы принимать перетаскиваемые данные. В этом фрагменте кода используется для подтверждения того, CanLoadObjects
что это представление таблицы может принимать строковые данные.
public bool CanHandleDropSession(UITableView tableView, IUIDropSession session)
{
return session.CanLoadObjects(typeof(NSString));
}
DropSessionDidUpdate
Метод DropSessionDidUpdate
вызывается многократно во время выполнения операции перетаскивания, чтобы предоставить визуальные подсказки пользователю.
В приведенном ниже коде используется для определения того, HasActiveDrag
возникла ли операция в текущем представлении таблицы. В этом случае можно переместить только отдельные строки.
Если перетаскивание находится из другого источника, операция копирования будет указана:
public UITableViewDropProposal DropSessionDidUpdate(UITableView tableView, IUIDropSession session, NSIndexPath destinationIndexPath)
{
// The UIDropOperation.Move operation is available only for dragging within a single app.
if (tableView.HasActiveDrag)
{
if (session.Items.Length > 1)
{
return new UITableViewDropProposal(UIDropOperation.Cancel);
} else {
return new UITableViewDropProposal(UIDropOperation.Move, UITableViewDropIntent.InsertAtDestinationIndexPath);
}
} else {
return new UITableViewDropProposal(UIDropOperation.Copy, UITableViewDropIntent.InsertAtDestinationIndexPath);
}
}
Операция удаления может быть одной из Cancel
, Move
или Copy
.
Целью удаления может быть вставка новой строки или добавление или добавление данных в существующую строку.
PerformDrop
Метод PerformDrop
вызывается, когда пользователь завершает операцию, и изменяет представление таблицы и источник данных для отражения удаленных данных.
public void PerformDrop(UITableView tableView, IUITableViewDropCoordinator coordinator)
{
NSIndexPath indexPath, destinationIndexPath;
if (coordinator.DestinationIndexPath != null)
{
indexPath = coordinator.DestinationIndexPath;
destinationIndexPath = indexPath;
}
else
{
// Get last index path of table view
var section = tableView.NumberOfSections() - 1;
var row = tableView.NumberOfRowsInSection(section);
destinationIndexPath = NSIndexPath.FromRowSection(row, section);
}
coordinator.Session.LoadObjects(typeof(NSString), (items) =>
{
// Consume drag items
List<string> stringItems = new List<string>();
foreach (var i in items)
{
var q = NSString.FromHandle(i.Handle);
stringItems.Add(q.ToString());
}
var indexPaths = new List<NSIndexPath>();
for (var j = 0; j < stringItems.Count; j++)
{
var indexPath1 = NSIndexPath.FromRowSection(destinationIndexPath.Row + j, destinationIndexPath.Section);
model.AddItem(stringItems[j], indexPath1.Row);
indexPaths.Add(indexPath1);
}
tableView.InsertRows(indexPaths.ToArray(), UITableViewRowAnimation.Automatic);
});
}
Для асинхронной загрузки больших объектов данных можно добавить дополнительный код.