SwiftUI использует модификатор OnDelete EditMode наряду с пользовательскими действиями свайпа в iOS 15

#ios #swiftui #editmode #swiftui-swipeactions

#iOS #свифтуи #режим редактирования #swiftui-swipeactions

Вопрос:

Первоначальное описание

В настоящее время у меня есть динамический список, и я использую встроенную editMode функцию SwiftUI и встроенную EditButton() функцию, чтобы позволить пользователю удалять элементы из списка.

Для части удаления я использую onDelete модификатор, который добавляет завершающий красный жест удаления, как вы сейчас.

Это пример:

 List {  ForEach(someList) { someElement in  Text(someElement.name)  }  .onDelete { (indexSet) in }  .onMove { (source, destination) in } } .toolbar {  ToolbarItem(placement: .navigationBarLeading) {  EditButton()  } } .environment(.editMode, $editMode)  

Цель

Теперь я также хочу использовать модификатор iOS 15 .swipeActions , который позволяет добавлять наши собственные начальные или конечные жесты свайпа.

Я хочу, чтобы пользователь также мог редактировать элемент списка, проводя пальцем вправо, поэтому я добавил ведущее действие свайпа в свою строку:

 Text(someElement.name) .swipeActions(edge: .leading) {  Button("Edit") { } }  

Действие кнопки, очевидно, будет содержать код, разрешающий выпуск.

Проблема

Использование .swipeActions модификатора нарушает нормальное поведение editMode и, в частности .onDelete , модификатора. Действительно, при такой настройке я больше не могу провести пальцем влево, чтобы удалить строку.

Итак, вот вопрос: как я могу использовать editMode .onDelete модификатор SwiftUI в списке наряду с моим собственным пользовательским leading действием свайпа ?

Minimal reproducible example

Xcode playgrounds, for iOS 15.

 import SwiftUI import PlaygroundSupport  struct SomeList: Identifiable {  let id: UUID = UUID()  var name: String }  let someList: [SomeList] = [  SomeList(name: "row1"),  SomeList(name: "row2"),  SomeList(name: "row3") ]  struct ContentView: View {  @State private var editMode = EditMode.inactive    var body: some View {  NavigationView {  List {  ForEach(someList) { someElement in  Text(someElement.name)  .swipeActions(edge: .leading) {  Button("Edit") { }  }  }  .onDelete { (indexSet) in }  .onMove { (source, destination) in }  }  .toolbar {  ToolbarItem(placement: .navigationBarLeading) {  EditButton()  }  }  .environment(.editMode, $editMode)  }  } }  PlaygroundPage.current.setLiveView(ContentView())  

Вы можете проверить следующее: если вы прокомментируете или удалите эту часть:

 .swipeActions(edge: .leading) {  Button("Edit") { } }  

Затем .onDelete модификатор снова работает. Включение его снова нарушает .onDelete функцию.

Дополнительная информация

Я создаю это приложение для iOS 15, так как использую .swipeActions модификатор.

Я готов принять любое решение, которое позволило бы достичь моей цели, а именно позволить пользователю провести пальцем влево, чтобы удалить строку, и провести пальцем вправо, чтобы запустить любой код редакции. Даже если это означает использование другого способа, чем .swipeActions модификатор , или другого способа, которым .onDelete модификатор SwiftUI editMode , или и того, и другого.

Мне пришлось создавать приложение для iOS 15 только из-за этого .swipeActions модификатора, поэтому, если я смогу создать приложение для более низких версий iOS, оно будет еще лучше.

Дайте мне знать сейчас, если вам нужна какая-либо дополнительная информация. Спасибо.

Комментарии:

1. Иногда полезно прочитать документацию: swipteActions — «При добавлении действий свайпа SwiftUI больше не синтезирует действия удаления, которые в противном случае появляются при использовании метода OnDelete(выполнить:) для каждого экземпляра. Вы становитесь ответственным за создание действия по удалению, если это необходимо, среди ваших действий по свайпу».

2. Действительно, я не читал эту часть документации, но я заметил такое поведение во время тестирования. Итак, что бы вы предложили по моему вопросу? Должен ли я прекратить использовать действия салфетки или мне следует реализовать свое собственное действие удаления?

3. Это ваше решение. Если вы хотите использовать .swipeActions() , вы должны выполнить свое собственное .onDelete() действие. Вы больше не получаете его бесплатно.

4. Вы можете добавить еще одну кнопку на панели инструментов. По сути, любой жест, кнопка и т. Д.-Это просто способ взаимодействия пользователя. Если вы закрываете один проспект, вам нужно использовать другой. Черт возьми, вы, вероятно, могли бы реализовать «встряску для редактирования», но это был бы необычный пользовательский интерфейс. Это действительно выходит за рамки мнений об пользовательском интерфейсе. И помните, вы можете использовать действия свайпа, вам просто нужно вставить туда действие для удаления.

5. Вы также можете протестировать версию iOS в своем приложении и представить наборы кода. Однако так было всегда, независимо от того, могли ли вы использовать его или нет .onDelete() .swipeActions() . Как только вы введете .swipeActions() свой код, он будет доступен только для iOS 15 . Опять же, это выбор разработчика.