Udostępnij za pośrednictwem


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:

Przykład przeciągania i upuszczania z aplikacji niestandardowej do aplikacji Notes

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 Cancelwartości , Movelub 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.