Přetažení v Xamarin.iOS

Implementace přetažení pro iOS 11

iOS 11 obsahuje podporu přetažení pro kopírování dat mezi aplikacemi na iPadu. Uživatelé můžou vybrat a přetáhnout všechny typy obsahu z aplikací umístěných vedle sebe nebo přetažením přes ikonu aplikace, která aktivuje otevření aplikace a povolení vyřazení dat:

Drag and drop example from custom app into Notes app

Poznámka:

Před iOSem 15 je přetažení dostupné jenom ve stejné aplikaci na i Telefon. iOS 15 zavádí přetahování mezi aplikacemi.

Zvažte podporu operací přetažení kdekoli, kde je možné vytvořit nebo upravit obsah:

  • Ovládací prvky textu podporují přetažení všech aplikací vytvořených v iOSu 11 bez další práce.
  • Zobrazení tabulek a zobrazení kolekcí zahrnují vylepšení v iOSu 11, která zjednodušují přidávání chování přetažení.
  • Jakékoli jiné zobrazení lze provést tak, aby podporovalo přetažení s dalšími přizpůsobeními.

Při přidávání podpory přetažení do vašich aplikací můžete poskytnout různé úrovně věrnosti obsahu; Můžete například zadat formátovaný text i verzi dat ve formátu prostého textu, aby přijímající aplikace mohla zvolit, která nejlépe vyhovuje cíli přetažení. Vizualizaci přetažení je také možné přizpůsobit a také povolit přetahování více položek najednou.

Přetažení pomocí textových ovládacích prvků

UITextView a UITextField automaticky podporuje přetahování vybraného textu a přetahování textového obsahu.

Přetažení pomocí UITableView

UITableView má integrované zpracování pro interakce přetažení s řádky tabulky, které vyžadují pouze několik metod pro povolení výchozího chování.

Existují dvě rozhraní:

  • IUITableViewDragDelegate – Informace o balíčcích při spuštění přetažení v zobrazení tabulky.
  • IUITableViewDropDelegate – Zpracovává informace při pokusu o odstranění a dokončení.

V dragAndDropTableView vzorek tyto dvě rozhraní jsou implementovány ve UITableViewController třídě spolu s delegátem a zdrojem dat. Přiřazují se v ViewDidLoad metodě:

this.TableView.DragDelegate = this;
this.TableView.DropDelegate = this;

Níže je vysvětlen minimální požadovaný kód pro tato dvě rozhraní.

Přetahování delegáta zobrazení tabulky

Jedinou metodou potřebnou k podpoře přetažení řádku ze zobrazení tabulky je GetItemsForBeginningDragSession. Pokud uživatel začne přetahovat řádek, bude volána tato metoda.

Níže je znázorněna implementace. Načte data přidružená k přetahovanému řádku, zakóduje je a nakonfiguruje NSItemProvider , která určuje, jak budou aplikace zpracovávat část operace "drop" (například jestli mohou zpracovávat datový typ, PlainTextv příkladu):

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) };
}

U delegáta přetažení existuje mnoho volitelných metod, které lze implementovat k přizpůsobení chování přetažení, například poskytnutí více reprezentací dat, které lze využít v cílových aplikacích (například formátovaný text, prostý text nebo vektorové a rastrové verze výkresu). Můžete také zadat vlastní reprezentace dat, které se mají použít při přetahování v rámci stejné aplikace.

Delegát přetažení zobrazení tabulky

Metody delegáta přetažení se volají, když dojde k operaci přetažení přes zobrazení tabulky nebo se dokončí nad ním. Požadované metody určují, jestli je možné data vynechat a jaké akce se provádějí, pokud je odstranění dokončené:

  • CanHandleDropSession – Zatímco probíhá přetažení a potenciálně se v aplikaci vynechá, tato metoda určuje, zda je možné přetažení dat.
  • DropSessionDidUpdate – Zatímco probíhá přetažení, tato metoda je volána k určení, jaká akce je zamýšlena. Informace z přetahovaného zobrazení tabulky, relace přetažení a možné cesty indexu se dají použít k určení chování a vizuální zpětné vazby poskytnuté uživateli.
  • PerformDrop – Když uživatel dokončí pokles (zvednutím prstu), tato metoda extrahuje data přetahovaná a upraví zobrazení tabulky tak, aby se data přidala do nového řádku (nebo řádků).

CanHandleDropSession

CanHandleDropSession určuje, zda zobrazení tabulky může přijmout přetahovaná data. V tomto fragmentu kódu se používá k potvrzení, CanLoadObjects že toto zobrazení tabulky může přijímat řetězcová data.

public bool CanHandleDropSession(UITableView tableView, IUIDropSession session)
{
  return session.CanLoadObjects(typeof(NSString));
}

DropSessionDidUpdate

Metoda DropSessionDidUpdate se volá opakovaně, zatímco probíhá operace přetažení, aby uživateli poskytla vizuální upozornění.

V následujícím kódu se používá k určení, HasActiveDrag jestli operace pochází z aktuálního zobrazení tabulky. Pokud ano, je možné přesunout pouze jeden řádek. Pokud je přetažení z jiného zdroje, zobrazí se operace kopírování:

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);
  }
}

Operace přetažení může být jedna z Cancel, Movenebo Copy.

Záměrem přetažení může být vložení nového řádku nebo přidání nebo přidání dat do existujícího řádku.

PerformDrop

Metoda PerformDrop se volá, když uživatel dokončí operaci a upraví zobrazení tabulky a zdroj dat tak, aby odrážel vyřazená data.

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);
  });
}

K asynchronnímu načtení velkých datových objektů je možné přidat další kód.

Testování přetažení

K otestování vzorku musíte použít iPad. Otevřete ukázku vedle jiné aplikace (například Poznámky) a přetáhněte řádky a text mezi nimi:

screenshot of drag operation in progress