Выделение SwiftUI NavigationLink остается выделенным после возврата к предыдущему виду

У меня есть серия представлений в SwiftUI. Один из них представляет собой представление меню, которое состоит из списка ссылок навигации, заключенных в представление навигации.

Код выглядит следующим образом.

var body: some View {
        NavigationView {
            List {
                HStack {
                    NavigationLink(destination: History(), isActive: $isHistoryViewActive) {
                    Image(systemName: "clock")                        
                    Text("History")                    
                    }
                }
                
                HStack {
                    NavigationLink(destination: Settings(), isActive: $isSettingsActive) {
                        Image(systemName: "gear")
                        Text("Settings")
                    }
                }
                
                HStack {
                    Image(systemName: "info.circle.fill")
                    Button(action: {
                        ...
                    }) {
                        Text("My Button")
                    }
                }
            }
        }
   }

Представление Настройки выглядит следующим образом

var body: some View {
     List {
        ...
        Section(header: "Background Music") {
           Toggle("Play", isOn: $isBackGroundMusicOn)
        }
           
        Section(header: "Voice Setting") {
           HStack {
              NavigationLink(destination: VoiceList() {
                 Text(self.voiceNames[self.selectedVoice])
           }
        }
     }
}

И, наконец, вид VoiceList выглядит следующим образом:

var body: some View {
        List {
            ForEach(0 ..< VoiceList.voiceNames.count) {voiceIndex in
                HStack {
                    Button(action: {
                        voiceChanged(selectedVoice: voiceIndex)
                    }){
                        Text(VoiceList.voiceNames[voiceIndex])
                    }
                    Spacer()
                    Image(systemName: "checkmark")
                        .frame(alignment: .trailing)
                        .foregroundColor(.blue)
                        .isHidden(hidden: voiceIndex != selectedVoice)
                }
            }
        }
}

Проблема, с которой я столкнулся, заключается в том, что, когда приложение возвращается из представления VoiceList в представление Настройки, NavigationLink остается выделенным, как если бы он все еще активен, как показано на прилагаемом снимке экрана. Честно говоря, я понятия не имею, что может быть причиной этого. Приветствуются любые идеи или идеи.

введите описание изображения здесь


person Peter Jacobs    schedule 22.12.2020    source источник


Ответы (2)


Вы можете использовать действие onReceive на List:

List {
    …
}.onReceive(NotificationCenter.default.publisher(for: UITableView.selectionDidChangeNotification)) {
    guard let tableView = $0.object as? UITableView,
          let selectedRow = tableView.indexPathForSelectedRow else { return }

    tableView.deselectRow(at: selectedRow, animated: true)
}

Это снимет выделение с выбранной строки.

Благодарим за первоначальную идею этого обходного пути Pivaisan (из этого потока разработчиков Apple) .

person Koraktor    schedule 13.03.2021
comment
Работал как шарм. Огромное спасибо! - person Peter Jacobs; 17.03.2021
comment
Это единственное решение, которое мне удалось найти в Xcode 12.5. - person rbaldwin; 19.06.2021

У меня была такая же проблема при работе со списком, чтобы решить эту проблему, я использую: UITableViewCell.appearance().selectionStyle = .none, но, как вы могли ожидать, у вас не будет аспекта выбора, поэтому правильный способ - попытаться сохранить состояние выбора и очистить, прежде чем покинуть экран, но в мои попытки, я понятия не имею, как это сделать.

Пример:

struct YourApp: App {
    
    init() {
        UITableView.appearance().backgroundColor = .clear
        UITableViewCell.appearance().selectionStyle = .none
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
person Wesley Brito    schedule 22.12.2020
comment
У меня это не сработало. Где именно вы разместили эту строку кода? - person Peter Jacobs; 23.12.2020
comment
В моем классе приложения @main я создал init () с этим кодом. Отредактирую ответ. - person Wesley Brito; 23.12.2020
comment
Предыстория для вашего дела не нужна. - person Wesley Brito; 23.12.2020
comment
Спасибо за ответ. На самом деле у меня нет класса приложения @main в моем приложении. Интересно, можно ли это альтернативно разместить в SceneDelegate или HostingController. В противном случае я займусь созданием класса приложения. - person Peter Jacobs; 24.12.2020
comment
вы также можете поместить его в свой appDelegate, не нужно создавать новый проект, если вы используете жизненный цикл uikit. - person Wesley Brito; 24.12.2020