Przeciąganie i upuszczanie na platformie Xamarin.iOS
Implementowanie przeciągania i upuszczania dla systemu iOS 11
System iOS 11 obejmuje obsługę przeciągania i upuszczania w celu kopiowania danych między aplikacjami na urządzeniu iPad. Użytkownicy mogą wybierać i przeciągać wszystkie typy zawartości z aplikacji umieszczonych obok siebie lub przeciągając ikonę aplikacji, która wyzwoli otwieranie aplikacji i umożliwia usunięcie danych:
Uwaga
Przed systemem iOS 15 przeciąganie i upuszczanie jest dostępne tylko w tej samej aplikacji w systemie i Telefon. System iOS 15 wprowadza przeciąganie i upuszczanie między aplikacjami.
Rozważ obsługę operacji przeciągania i upuszczania w dowolnym miejscu, w których można tworzyć lub edytować zawartość:
- Kontrolki tekstu obsługują przeciąganie i upuszczanie dla wszystkich aplikacji utworzonych w systemie iOS 11 bez dodatkowej pracy.
- Widoki tabel i widoki kolekcji obejmują ulepszenia w systemie iOS 11, które upraszczają dodawanie zachowania przeciągania i upuszczania.
- Każdy inny widok można wykonać w celu obsługi przeciągania i upuszczania z dodatkowym dostosowaniem.
Podczas dodawania obsługi przeciągania i upuszczania do aplikacji można zapewnić różne poziomy wierności zawartości; Na przykład możesz podać zarówno sformatowany tekst, jak i wersję zwykłego tekstu danych, aby aplikacja odbierającego mogła wybrać, które najlepiej pasuje do obiektu docelowego przeciągania. Można również dostosować wizualizację przeciągania, a także włączyć przeciąganie wielu elementów jednocześnie.
Przeciąganie i upuszczanie za pomocą kontrolek tekstu
UITextView
i UITextField
automatycznie obsługują przeciąganie zaznaczonego tekstu i upuszczanie zawartości tekstowej.
Przeciąganie i upuszczanie za pomocą kontrolki UITableView
UITableView
Ma wbudowaną obsługę interakcji przeciągania i upuszczania z wierszami tabeli, co wymaga tylko kilku metod włączenia domyślnego zachowania.
Istnieją dwa interfejsy:
IUITableViewDragDelegate
— Informacje o pakietach po zainicjowaniu przeciągania w widoku tabeli.IUITableViewDropDelegate
— przetwarza informacje o próbie i zakończeniu upuszczania.
W przykładzie te dwa interfejsy są implementowane w UITableViewController
klasie wraz z delegatem i źródłem danych. Są one przypisywane w metodzie ViewDidLoad
:
this.TableView.DragDelegate = this;
this.TableView.DropDelegate = this;
Poniżej wyjaśniono minimalny wymagany kod dla tych dwóch interfejsów.
Przeciąganie delegata widoku tabeli
Jedyną metodą wymaganą do obsługi przeciągania wiersza z widoku tabeli jest GetItemsForBeginningDragSession
. Jeśli użytkownik zacznie przeciągać wiersz, zostanie wywołana ta metoda.
Poniżej przedstawiono implementację. Pobiera dane skojarzone z przeciąganym wierszem, koduje je i konfiguruje NSItemProvider
, który określa, w jaki sposób aplikacje będą obsługiwać część operacji "drop" (na przykład czy mogą obsługiwać typ danych, PlainText
, w tym przykładzie):
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) };
}
Istnieje wiele opcjonalnych metod delegata przeciągania, które można zaimplementować, aby dostosować zachowanie przeciągania, takie jak dostarczanie wielu reprezentacji danych, które można wykorzystać w aplikacjach docelowych (takich jak sformatowany tekst, a także zwykły tekst lub wektor i wersje mapy bitowej rysunku). Możesz również podać niestandardowe reprezentacje danych, które mają być używane podczas przeciągania i upuszczania w tej samej aplikacji.
Delegat porzucania widoku tabeli
Metody delegata upuszczania są wywoływane, gdy operacja przeciągania odbywa się w widoku tabeli lub kończy się nad nim. Wymagane metody określają, czy dane mogą zostać porzucone, oraz jakie akcje są podejmowane w przypadku zakończenia upuszczania:
CanHandleDropSession
— Podczas gdy przeciąganie jest w toku i potencjalnie spada w aplikacji, ta metoda określa, czy przeciągane dane mogą zostać porzucone.DropSessionDidUpdate
— Podczas gdy przeciąganie jest w toku, ta metoda jest wywoływana w celu określenia, jaka akcja jest przeznaczona. Informacje z widoku tabeli przeciągniętego, sesji przeciągania i możliwej ścieżki indeksu mogą służyć do określania zachowania i wizualnej opinii przekazanej użytkownikowi.PerformDrop
— Gdy użytkownik ukończy upuszczanie (przez podniesienie palca), ta metoda wyodrębnia przeciągane dane i modyfikuje widok tabeli w celu dodania danych w nowym wierszu (lub wierszach).
CanHandleDropSession
CanHandleDropSession
wskazuje, czy widok tabeli może zaakceptować przeciągane dane. W tym fragmencie kodu służy do potwierdzenia, CanLoadObjects
że ten widok tabeli może akceptować dane ciągów.
public bool CanHandleDropSession(UITableView tableView, IUIDropSession session)
{
return session.CanLoadObjects(typeof(NSString));
}
DropSessionDidUpdate
Metoda DropSessionDidUpdate
jest wywoływana wielokrotnie, gdy operacja przeciągania jest w toku, aby zapewnić użytkownikowi wskazówki wizualne.
W poniższym kodzie służy do określania, HasActiveDrag
czy operacja pochodzi z bieżącego widoku tabeli. Jeśli tak, można przenosić tylko pojedyncze wiersze.
Jeśli przeciąganie pochodzi z innego źródła, zostanie wskazana operacja kopiowania:
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);
}
}
Operacja upuszczania może być jedną z Cancel
wartości , Move
lub Copy
.
Intencją upuszczania może być wstawianie nowego wiersza lub dodawanie/dołączanie danych do istniejącego wiersza.
PerformDrop
Metoda PerformDrop
jest wywoływana, gdy użytkownik ukończy operację, i modyfikuje widok tabeli i źródło danych w celu odzwierciedlenia porzuconych danych.
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);
});
}
Do asynchronicznego ładowania dużych obiektów danych można dodać dodatkowy kod.