Edytowanie tabel za pomocą platformy Xamarin.iOS
Funkcje edycji tabel są włączone przez zastępowanie metod w podklasie UITableViewSource
. Najprostszym zachowaniem edycji jest gest przesunięcia do usunięcia, który można zaimplementować za pomocą przesłonięcia jednej metody.
Bardziej złożone edytowanie (w tym przenoszenie wierszy) można wykonać za pomocą tabeli w trybie edycji.
Szybkie przesunięcie w celu usunięcia
Funkcja szybkiego przesunięcia do usunięcia jest naturalnym gestem w systemie iOS, którego oczekują użytkownicy.
Istnieją trzy przesłonięcia metody, które wpływają na gest przesunięcia, aby wyświetlić przycisk Usuń w komórce:
- CommitEditingStyle — źródło tabeli wykrywa, czy ta metoda jest zastępowana i automatycznie włącza gest przesunięcia do usunięcia. Implementacja metody powinna wywołać
DeleteRows
UITableView
metodę , aby spowodować zniknięcie komórek, a także usunąć dane bazowe z modelu (na przykład tablicę, słownik lub bazę danych). - CanEditRow — jeśli wartość CommitEditingStyle jest zastępowana, przyjmuje się, że wszystkie wiersze są edytowalne. Jeśli ta metoda jest implementowana i zwraca wartość false (dla niektórych określonych wierszy lub dla wszystkich wierszy), gest przesunięcia do usunięcia nie będzie dostępny w tej komórce.
- TitleForDeleteConfirmation — opcjonalnie określa tekst przycisku Usuń . Jeśli ta metoda nie zostanie zaimplementowana, tekst przycisku będzie "Usuń".
Te metody są implementowane w TableSource
klasie:
public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, Foundation.NSIndexPath indexPath)
{
switch (editingStyle) {
case UITableViewCellEditingStyle.Delete:
// remove the item from the underlying data source
tableItems.RemoveAt(indexPath.Row);
// delete the row from the table
tableView.DeleteRows (new NSIndexPath[] { indexPath }, UITableViewRowAnimation.Fade);
break;
case UITableViewCellEditingStyle.None:
Console.WriteLine ("CommitEditingStyle:None called");
break;
}
}
public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath)
{
return true; // return false if you wish to disable editing for a specific indexPath or for all rows
}
public override string TitleForDeleteConfirmation (UITableView tableView, NSIndexPath indexPath)
{ // Optional - default text is 'Delete'
return "Trash (" + tableItems[indexPath.Row].SubHeading + ")";
}
W tym przykładzie UITableViewSource
element został zaktualizowany tak, aby używał List<TableItem>
tablicy (zamiast tablicy ciągów) jako źródła danych, ponieważ obsługuje dodawanie i usuwanie elementów z kolekcji.
Tryb edycji
Gdy tabela jest w trybie edycji, użytkownik zobaczy czerwony widżet "zatrzymaj" w każdym wierszu, który wyświetla przycisk Usuń po naciśnięciu. W tabeli jest również wyświetlana ikona "uchwyt", aby wskazać, że wiersz można przeciągnąć, aby zmienić kolejność. Przykład TableEditMode implementuje te funkcje, jak pokazano poniżej.
Istnieje wiele różnych metod UITableViewSource
, które mają wpływ na zachowanie trybu edycji tabeli:
- CanEditRow — czy można edytować każdy wiersz. Zwróć wartość false, aby uniemożliwić zarówno szybkie przesunięcie do usunięcia, jak i usunięcie w trybie edycji.
- CanMoveRow — zwraca wartość true, aby umożliwić przenoszenie "dojścia" lub "false", aby zapobiec przeniesieniu.
- EditStyleForRow — gdy tabela jest w trybie edycji, zwracana wartość z tej metody określa, czy komórka wyświetla czerwoną ikonę usuwania, czy zieloną ikonę dodawania. Zwróć,
UITableViewCellEditingStyle.None
jeśli wiersz nie powinien być edytowalny. - MoveRow — wywoływana po przeniesieniu wiersza, aby można było zmodyfikować podstawową strukturę danych tak, aby była zgodna z danymi wyświetlanymi w tabeli.
Implementacja pierwszych trzech metod jest stosunkowo prosta — chyba że chcesz użyć polecenia indexPath
, aby zmienić zachowanie określonych wierszy, po prostu zakoduj wartości zwracane dla całej tabeli.
public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath)
{
return true; // return false if you wish to disable editing for a specific indexPath or for all rows
}
public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath)
{
return true; // return false if you don't allow re-ordering
}
public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath)
{
return UITableViewCellEditingStyle.Delete; // this example doesn't support Insert
}
Implementacja jest nieco bardziej skomplikowana MoveRow
, ponieważ musi zmienić podstawową strukturę danych, aby dopasować ją do nowej kolejności. Ponieważ dane są implementowane jako List
poniższy kod, usuwa element danych w swojej starej lokalizacji i wstawia je w nowej lokalizacji. Jeśli dane były przechowywane w tabeli bazy danych SQLite z kolumną "order" (na przykład), ta metoda musiałaby wykonać niektóre operacje SQL, aby zmienić kolejność liczb w tej kolumnie.
public override void MoveRow (UITableView tableView, NSIndexPath sourceIndexPath, NSIndexPath destinationIndexPath)
{
var item = tableItems[sourceIndexPath.Row];
var deleteAt = sourceIndexPath.Row;
var insertAt = destinationIndexPath.Row;
// are we inserting
if (destinationIndexPath.Row < sourceIndexPath.Row) {
// add one to where we delete, because we're increasing the index by inserting
deleteAt += 1;
} else {
// add one to where we insert, because we haven't deleted the original yet
insertAt += 1;
}
tableItems.Insert (insertAt, item);
tableItems.RemoveAt (deleteAt);
}
Na koniec, aby uzyskać tabelę w trybie edycji, przycisk Edytuj musi wywołać SetEditing
metodę podobną do tej
table.SetEditing (true, true);
a po zakończeniu edytowania przez użytkownika przycisk Gotowe powinien wyłączyć tryb edycji:
table.SetEditing (false, true);
Styl edycji wstawiania wierszy
Wstawianie wierszy z tabeli jest nietypowym interfejsem użytkownika — głównym przykładem standardowych aplikacji systemu iOS jest ekran Edytowanie kontaktu . Ten zrzut ekranu przedstawia działanie funkcji wstawiania wierszy — w trybie edycji istnieje dodatkowy wiersz, który (po kliknięciu) wstawia dodatkowe wiersze do danych. Po zakończeniu edycji zostanie usunięty tymczasowy (dodaj nowy) wiersz.
Istnieje wiele różnych metod, które UITableViewSource
mają wpływ na zachowanie trybu edycji tabeli. Te metody zostały zaimplementowane w następujący sposób w przykładowym kodzie:
- EditingStyleForRow — zwraca
UITableViewCellEditingStyle.Delete
wiersze zawierające dane i zwracaUITableViewCellEditingStyle.Insert
ostatni wiersz (który zostanie dodany specjalnie do zachowania się jako przycisk wstawiania). - CustomizeMoveTarget — gdy użytkownik przenosi komórkę, wartość zwracana z tej opcjonalnej metody może zastąpić wybór lokalizacji. Oznacza to, że można uniemożliwić im "upuszczanie" komórki w określonych pozycjach — na przykład w tym przykładzie uniemożliwia przenoszenie dowolnego wiersza po wierszu (dodaj nowy).
- CanMoveRow — zwraca wartość true, aby umożliwić przenoszenie "dojścia" lub "false", aby zapobiec przeniesieniu. W tym przykładzie ostatni wiersz ma ukryty ruch "uchwyt", ponieważ jest przeznaczony tylko do serwera jako przycisk wstawiania.
Dodamy również dwie metody niestandardowe, aby dodać wiersz "insert", a następnie usunąć go ponownie, gdy nie jest już wymagany. Są one wywoływane z przycisków Edytuj i Gotowe :
- WillBeginTableEditing — gdy przycisk Edytuj jest dotykany, wywołuje
SetEditing
polecenie , aby umieścić tabelę w trybie edycji. Spowoduje to wyzwolenie metody WillBeginTableEditing, w której na końcu tabeli jest wyświetlany wiersz (dodaj nowy), który będzie działać jako przycisk wstawiania. - DidFinishTableEditing — gdy przycisk Gotowe jest ponownie wywoływany
SetEditing
, aby wyłączyć tryb edycji. Przykładowy kod usuwa wiersz (dodaj nowy) z tabeli, gdy edytowanie nie jest już wymagane.
Te przesłonięcia metod są implementowane w przykładowym pliku TableEditModeAdd/Code/TableSource.cs:
public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath)
{
if (tableView.Editing) {
if (indexPath.Row == tableView.NumberOfRowsInSection (0) - 1)
return UITableViewCellEditingStyle.Insert;
else
return UITableViewCellEditingStyle.Delete;
} else // not in editing mode, enable swipe-to-delete for all rows
return UITableViewCellEditingStyle.Delete;
}
public override NSIndexPath CustomizeMoveTarget (UITableView tableView, NSIndexPath sourceIndexPath, NSIndexPath proposedIndexPath)
{
var numRows = tableView.NumberOfRowsInSection (0) - 1; // less the (add new) one
if (proposedIndexPath.Row >= numRows)
return NSIndexPath.FromRowSection(numRows - 1, 0);
else
return proposedIndexPath;
}
public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath)
{
return indexPath.Row < tableView.NumberOfRowsInSection (0) - 1;
}
Te dwie metody niestandardowe służą do dodawania i usuwania wiersza (dodaj nowy), gdy tryb edycji tabeli jest włączony lub wyłączony:
public void WillBeginTableEditing (UITableView tableView)
{
tableView.BeginUpdates ();
// insert the 'ADD NEW' row at the end of table display
tableView.InsertRows (new NSIndexPath[] {
NSIndexPath.FromRowSection (tableView.NumberOfRowsInSection (0), 0)
}, UITableViewRowAnimation.Fade);
// create a new item and add it to our underlying data (it is not intended to be permanent)
tableItems.Add (new TableItem ("(add new)"));
tableView.EndUpdates (); // applies the changes
}
public void DidFinishTableEditing (UITableView tableView)
{
tableView.BeginUpdates ();
// remove our 'ADD NEW' row from the underlying data
tableItems.RemoveAt ((int)tableView.NumberOfRowsInSection (0) - 1); // zero based :)
// remove the row from the table display
tableView.DeleteRows (new NSIndexPath[] { NSIndexPath.FromRowSection (tableView.NumberOfRowsInSection (0) - 1, 0) }, UITableViewRowAnimation.Fade);
tableView.EndUpdates (); // applies the changes
}
Na koniec ten kod tworzy wystąpienie przycisków Edytuj i Gotowe, z lambdami, które włączają lub wyłączają tryb edycji po dotknięciu:
done = new UIBarButtonItem(UIBarButtonSystemItem.Done, (s,e)=>{
table.SetEditing (false, true);
NavigationItem.RightBarButtonItem = edit;
tableSource.DidFinishTableEditing(table);
});
edit = new UIBarButtonItem(UIBarButtonSystemItem.Edit, (s,e)=>{
if (table.Editing)
table.SetEditing (false, true); // if we've half-swiped a row
tableSource.WillBeginTableEditing(table);
table.SetEditing (true, true);
NavigationItem.LeftBarButtonItem = null;
NavigationItem.RightBarButtonItem = done;
});
Ten wzorzec interfejsu użytkownika wstawiania wierszy nie jest często używany, ale można również użyć UITableView.BeginUpdates
metod i EndUpdates
do animowania wstawiania lub usuwania komórek w dowolnej tabeli. Reguła użycia tych metod polega na tym, że różnica wartości zwracanej między RowsInSection
BeginUpdates
wywołaniami i EndUpdates
musi odpowiadać liczbie komórek dodanych/usuniętych za pomocą InsertRows
metod i DeleteRows
. Jeśli bazowe źródło danych nie zostanie zmienione w celu dopasowania do wstawiania/usuwania w widoku tabeli, wystąpi błąd.