Выбор списка SwiftUI: нужно дважды нажать, чтобы отменить выбор элемента изначально

Почему вам нужно дважды нажать, чтобы отменить выбор «Элемент 1»? Я делаю что-то неправильно? Если нет, есть ли обходной путь? Это происходит как в симуляторе, так и на моем iPhone.

Шаги:

  1. Нажмите «Элемент 1». Ничего не произошло. Не касайтесь другого элемента первым. Кроме того, это происходит только один раз, поэтому перезапустите приложение, чтобы повторить попытку.
  2. Нажмите «Элемент 1» еще раз. Он не выбран.
import SwiftUI

struct ContentView: View {
    @State private var selectedItems: Set<Int> = [1]
    
    var body: some View {
        NavigationView { // Some apparent solutions do not work inside a NavigationView
            List(selection: $selectedItems) {
                Text("Item 1").tag(1)
                Text("Item 2").tag(2)
                Text("Item 3").tag(3)
            }.environment(\.editMode, Binding.constant(EditMode.active))
        }
    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
33
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не знаю почему, но, кажется, это доступ к .environment.
У меня работает классическая переменная @Environment:

struct ContentView: View {
    
    @State private var selectedItems: Set<Int> = [1]
    @Environment(\.editMode) var editMode
    
    var body: some View {
        
        List(selection: $selectedItems) {
            Text("Item 1").tag(1)
            Text("Item 2").tag(2)
            Text("Item 3").tag(3)
        }
//        .environment(\.editMode, Binding.constant(EditMode.active))
        
        // try this instead
        .onAppear {
            editMode?.wrappedValue = EditMode.active
        }
    }
}

К сожалению, это не работает для меня в NavigationView. EditButton работает, но программная установка EditMode не активирует редактирование. С помощью DispatchQueue.main.async это работает, но я не знаю, почему.

John 15.05.2022 09:29

Проблема, похоже, связана с ScenePhase (активный, неактивный, фоновый). Отсутствующие элементы управления выбором появляются при нажатии кнопки «Домой» и повторном открытии приложения.

John 15.05.2022 10:11

кажется, что он должен сначала нарисовать вид, прежде чем он сможет активировать режим редактирования. Так что следовать вашей идее DispatchQueue и, возможно, немного времени задержки может быть хорошо.

ChrisR 15.05.2022 10:12

Я обнаружил, что вы также можете сохранить исходный .environment(\.editMode, Binding... и установить selectedItems в onAppear с помощью DispatchQueue.main.async. Это предотвращает активацию EditMode в других представлениях (в противном случае вам придется реализовать onDisappear при использовании DispatchQueue).

John 15.05.2022 10:47

Лучшее решение: прикрепить onAppear к чему-то внутри списка (ForEach или в данном случае Text) и установить там выбор (без DispatchQueue). Используйте оригинальный .environment(\.editMode, Binding... в списке.

John 15.05.2022 10:59
Ответ принят как подходящий

Чтобы предотвратить проблему двойного щелчка, установите выделение в onAppearвнутри в списке:

import SwiftUI

struct ContentView: View {
    @State private var selectedItems: Set<Int> = []
    
    var body: some View {
        NavigationView { // Some apparent solutions do not work inside a NavigationView
            List(selection: $selectedItems) {
                Text("Item 1").tag(1)
                Text("Item 2").tag(2)
                Text("Item 3").tag(3).onAppear() { // onAppear inside the List!
                    selectedItems = [1]
                }
            }.environment(\.editMode, Binding.constant(EditMode.active))
        }
    }
}

Обратите внимание, что этот пример кода устанавливает один и тот же выбор для каждого onAppear. В зависимости от того, как должно вести себя ваше приложение, вам придется изменить его.

Другие вопросы по теме