web-dev-qa-db-fra.com

Comment activer un balayage pour modifier l'action dans la liste à l'aide de SwiftUI?

J'essaie d'implémenter un balayage pour modifier l'action à l'aide de SwiftUI. Une action de suppression et une action de déplacement fonctionnent toutes les deux parfaitement, mais je ne sais pas comment activer un balayage pour modifier l'action.

Je souhaite ouvrir l'écran d'édition lorsque l'utilisateur activera un balayage pour modifier l'action.

Voici mon code:

struct TableView : View {
@State var dataSource = DataSource()

var body: some View {
        NavigationView {
            List {
                ForEach(dataSource.pokemons.identified(by: \.id)) { pokemon in
                    Text(pokemon.name) 
                }
                .onDelete(perform: deletePokemon)
                .onMove(perform: movePokemon)
            }
            .navigationBarItems(leading: EditButton(), trailing: Button(action: addPokemon, label: { Text("Add") }))
            .navigationBarTitle(Text("Pokemons"))
        }
}
8
czater

Vous devez utiliser EditButton () à la place. Il active le mode d'édition pour un composant List.

1
Mecid

Je ne pense pas que ce soit possible actuellement.

La meilleure suggestion que j'ai est de lancer votre propre solution en utilisant UITableView via le protocole UIViewRepresentable. Cela étant dit, il pourrait y avoir des solutions open source viables.

Je pense que l'espoir de toutes les fonctionnalités de UITableView que vous voudrez peut être risqué parce que List est censé être un type "générique" qui est pris en charge sur différentes plates-formes. Certaines fonctionnalités de UITableView peuvent ne jamais arriver à un List.

Il s'agit d'un code rapide que j'ai tapé, mais il donne un exemple simple de création d'une solution UITableView personnalisée:

RoutineTableView(routines: routineDataSource.routines)
  .trailingSwipeActionsConfiguration {
    let editAction = UIContextualAction(
      style: .normal,
      title: "EDIT"
    ) { (action, sourceView, completionHandler) in

      completionHandler(true)
    }
    editAction.backgroundColor = UIColor.darkGray
    let deleteAction = UIContextualAction(
      style: .destructive,
      title: "DELETE"
    ) { (action, sourceView, completionHandler) in

      completionHandler(true)
    }
    let actions = [deleteAction, editAction]
    let configuration = UISwipeActionsConfiguration(actions: actions)
    return configuration
  }
  .onCellPress {
    print("hi there")
  }
  .navigationBarTitle("Routines")
private class CustomDataSource<SectionType: Hashable, ItemType: Hashable>: UITableViewDiffableDataSource<SectionType, ItemType> {

  override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
  }
}

struct RoutineTableView: UIViewRepresentable {

  let routines: [Routine]
  private var onCellPress: (() -> Void)? = nil
  private var trailingSwipeActionsConfiguration: (() -> UISwipeActionsConfiguration)? = nil

  init(routines: [Routine]) {
    self.routines = routines
  }

  func makeUIView(
    context: UIViewRepresentableContext<RoutineTableView>
  ) -> UITableView {
    let tableView = UITableView()
    context.coordinator.update(withTableView: tableView)
    return tableView
  }

  func updateUIView(_ uiView: UITableView, context: UIViewRepresentableContext<RoutineTableView>) {
    context.coordinator.update(routines: routines)
  }

  // MARK: - Coordinator

  func makeCoordinator() -> RoutineTableView.Coordinator {
    return Coordinator(self)
  }

  class Coordinator: NSObject, UITableViewDelegate {

    private enum Section {
      case first
    }

    private let view: RoutineTableView
    private var dataSource: UITableViewDiffableDataSource<Section, Routine>?

    init(_ view: RoutineTableView) {
      self.view = view
      super.init()
    }

    func update(withTableView tableView: UITableView) {
      tableView.register(RoutineTableViewCell.self)
      tableView.delegate = self

      let dataSource = CustomDataSource<Section, Routine>(tableView: tableView) { (tableView, indexPath, routine) -> UITableViewCell? in
        let cell: RoutineTableViewCell = tableView.dequeueReusableCell(for: indexPath)
        cell.configure(withRoutine: routine)
        return cell
      }
      self.dataSource = dataSource
    }

    func update(routines: [Routine]) {
      var snapshot = NSDiffableDataSourceSnapshot<Section, Routine>()
      snapshot.appendSections([.first])
      snapshot.appendItems(routines)
      dataSource?.apply(snapshot, animatingDifferences: true)
    }

    // MARK: - <UITableViewDelegate>

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      view.onCellPress?()
    }

    func tableView(
      _ tableView: UITableView,
      trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
    ) -> UISwipeActionsConfiguration? {
      return view.trailingSwipeActionsConfiguration?()
    }

  }
}

extension RoutineTableView {

  func onCellPress(
    _ onCellPress: @escaping () -> Void
  ) -> RoutineTableView {
    var view = self
    view.onCellPress = onCellPress
    return view
  }

  func trailingSwipeActionsConfiguration(
    _ trailingSwipeActionsConfiguration: @escaping () -> UISwipeActionsConfiguration
  ) -> RoutineTableView {
    var view = self
    view.trailingSwipeActionsConfiguration = trailingSwipeActionsConfiguration
    return view
  }
}
1
kgaidis

Hou la la! Hmmmm, je ne suis pas sûr d'utiliser un EditButton ()!

Je suppose que vous avez une liste et que vous souhaitez faire glisser la ligne et voir un choix à supprimer, non?

Tout ce que vous avez à faire est d'implémenter .onDelete(perform: delete) après la fermeture de la liste. Ensuite, ajoutez une fonction à la structure qui définit la fonction de suppression dans laquelle vous gérez la fermeture. N'oubliez pas que la fonction sera définie comme: func delete (at offsets: IndexSet) {}

Ajoutez ce que j'ai suggéré et compilez même sans que le corps de la fonction soit terminé (c'est-à-dire ajoutez un espace réservé print ()) et vous pouvez voir le comportement de balayage pour la suppression.

1
Justin Ngan