Trascinare e rilasciare in Xamarin.iOS
Implementazione del trascinamento della selezione per iOS 11
iOS 11 include il supporto per il trascinamento della selezione per copiare i dati tra le applicazioni nell'iPad. Gli utenti possono selezionare e trascinare tutti i tipi di contenuto dalle app posizionate side-by-side oppure trascinando su un'icona dell'app che attiverà l'apertura dell'app e per consentire l'eliminazione dei dati:
Nota
Prima di iOS 15, il trascinamento della selezione è disponibile solo all'interno della stessa app in i Telefono. iOS 15 introduce il trascinamento e la selezione tra app.
È consigliabile supportare le operazioni di trascinamento della selezione ovunque sia possibile creare o modificare il contenuto:
- I controlli di testo supportano il trascinamento della selezione per tutte le app compilate in iOS 11, senza ulteriori operazioni.
- Le visualizzazioni tabella e le visualizzazioni raccolta includono miglioramenti in iOS 11 che semplificano l'aggiunta del comportamento di trascinamento della selezione.
- È possibile creare qualsiasi altra visualizzazione per supportare il trascinamento della selezione con una personalizzazione aggiuntiva.
Quando si aggiunge il supporto per il trascinamento della selezione alle app, è possibile fornire livelli diversi di fedeltà del contenuto; Ad esempio, potresti fornire sia una versione formattata di testo che una versione di testo normale dei dati in modo che l'app ricevente possa scegliere quale sia più adatta alla destinazione di trascinamento. È anche possibile personalizzare la visualizzazione di trascinamento e anche per abilitare il trascinamento di più elementi contemporaneamente.
Trascinare e rilasciare con i controlli di testo
UITextView
e UITextField
supportano automaticamente il trascinamento del testo selezionato e l'eliminazione del contenuto di testo.
Trascinare e rilasciare con UITableView
UITableView
include la gestione predefinita per le interazioni di trascinamento e rilascio con righe di tabella, che richiedono solo alcuni metodi per abilitare il comportamento predefinito.
Sono presenti due interfacce:
IUITableViewDragDelegate
: consente di creare pacchetti quando viene avviato un trascinamento nella visualizzazione tabella.IUITableViewDropDelegate
: elabora le informazioni quando viene tentata e completata un'eliminazione.
Nell'esempio queste due interfacce sono entrambe implementate nella UITableViewController
classe , insieme al delegato e all'origine dati. Vengono assegnati nel ViewDidLoad
metodo :
this.TableView.DragDelegate = this;
this.TableView.DropDelegate = this;
Il codice minimo necessario per queste due interfacce è illustrato di seguito.
Delegato trascinamento vista tabella
L'unico metodo necessario per supportare il trascinamento di una riga da una vista tabella è GetItemsForBeginningDragSession
. Se l'utente inizia a trascinare una riga, questo metodo verrà chiamato.
Di seguito è illustrata un'implementazione. Recupera i dati associati alla riga trascinata, li codifica e configura un oggetto NSItemProvider
che determina come le applicazioni gestiranno la parte "drop" dell'operazione, ad esempio se possono gestire il tipo di dati, , PlainText
nell'esempio:
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) };
}
Esistono molti metodi facoltativi sul delegato di trascinamento che possono essere implementati per personalizzare il comportamento di trascinamento, ad esempio fornire più rappresentazioni di dati che possono essere sfruttate nelle app di destinazione (ad esempio testo formattato, testo normale o versioni vettoriali e bitmap di un disegno). È anche possibile fornire rappresentazioni di dati personalizzate da usare durante il trascinamento e l'eliminazione all'interno della stessa app.
Delegato di rilascio visualizzazione tabella
I metodi nel delegato di rilascio vengono chiamati quando si verifica un'operazione di trascinamento su una vista tabella o viene completato sopra di esso. I metodi necessari determinano se i dati possono essere eliminati e quali azioni vengono eseguite se l'eliminazione viene completata:
CanHandleDropSession
- Mentre è in corso un trascinamento e potenzialmente viene eliminato nell'applicazione, questo metodo determina se i dati trascinati possono essere eliminati.DropSessionDidUpdate
– Mentre il trascinamento è in corso, questo metodo viene chiamato per determinare l'azione desiderata. Le informazioni della vista tabella trascinate, la sessione di trascinamento e il percorso di indice possibile possono essere usati tutti per determinare il comportamento e il feedback visivo fornito all'utente.PerformDrop
: quando l'utente completa l'eliminazione (sollevando il dito), questo metodo estrae i dati trascinati e modifica la visualizzazione tabella per aggiungere i dati in una nuova riga (o righe).
CanHandleDropSession
CanHandleDropSession
indica se la vista tabella può accettare i dati trascinati. In questo frammento di CanLoadObjects
codice viene usato per confermare che questa vista tabella può accettare dati stringa.
public bool CanHandleDropSession(UITableView tableView, IUIDropSession session)
{
return session.CanLoadObjects(typeof(NSString));
}
DropSessionDidUpdate
Il DropSessionDidUpdate
metodo viene chiamato ripetutamente mentre l'operazione di trascinamento è in corso, per fornire segnali visivi all'utente.
Nel codice seguente HasActiveDrag
viene usato per determinare se l'operazione ha avuto origine nella visualizzazione tabella corrente. In tal caso, è consentito spostare solo singole righe.
Se il trascinamento proviene da un'altra origine, verrà indicata un'operazione di copia:
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);
}
}
L'operazione di rilascio può essere una di Cancel
, Move
o Copy
.
La finalità di rilascio può essere quella di inserire una nuova riga o aggiungere/aggiungere dati a una riga esistente.
PerformDrop
Il PerformDrop
metodo viene chiamato quando l'utente completa l'operazione e modifica la vista tabella e l'origine dati in modo da riflettere i dati eliminati.
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);
});
}
È possibile aggiungere codice aggiuntivo per caricare in modo asincrono oggetti dati di grandi dimensioni.