Udostępnij za pośrednictwem


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.

Przykład przesunięcia do usunięcia

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ć DeleteRowsUITableView 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.

Przykład TableEditMode implementuje te funkcje, jak pokazano

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.

Po zakończeniu edycji zostanie usunięty tymczasowy dodawanie nowego wiersza

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 zwraca UITableViewCellEditingStyle.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 RowsInSectionBeginUpdates 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.