微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI NavigationLink 在导航到详细信息视图时清除父视图的数据

如何解决SwiftUI NavigationLink 在导航到详细信息视图时清除父视图的数据

父视图包含SearchBarForEach List,列表中的每一项都包裹在NavigationLink 项中,问题是父列表。在 NavigationLink 中点击 ForEach 后它会被清除,我还为 UUID() 添加ForEach,但发生了同样的问题。我使用的是 Xcode 12.4,同样的问题发生在 iOS 13 和 14 上。

搜索视图

import SwiftUI

struct SearchView: View {
  @Observedobject var simpleSearchMV = SimpleSearchModelView()

  var body: some View {
    vstack{
      SearchBar(searchTerm: self.$simpleSearchMV.searchText)
        .padding(.vertical,10)
      ScrollView(showsIndicators: false) {
        ForEach(simpleSearchMV.dataResult.result ?? [],id: \.self.Id) { item in
          NavigationLink(destination: OffersView()) {
            Text(item.currentName)
          }

          Divider()
        }
        .id(UUID())
      }
    }
  }
}

SimpleSearchModelView

import Foundation
import Combine
import SwiftUI
import Alamofire

class SimpleSearchModelView: ObservableObject,Identifiable {

  @Observedobject var monitor = NetworkMonitor()

  @Published var dataResult: DataResult<[SearchSimpleResult]> = DataResult(loading: false)
  @Published var searchText: String = String()

  private var subscription: Set<AnyCancellable> = []

  init() {
    self.setSearchText()
  }

  func setSearchText() {
    $searchText
      .debounce(for: .milliseconds(500),scheduler: RunLoop.main) // debounces the string publisher,such that it delays the process of sending request to Remote Server.
      .removeDuplicates()
      .map({ (string) -> String? in
        if string.count < 1 {
          // self.dataResult.setData([])
          return nil
        }
        return string
      }) // prevents sending numerous requests and sends nil if the count of the characters is less than 1.
      .compactMap{ $0 } // removes the nil values so the search string does not get passed down to the publisher chain
      .sink { (_) in
        //
      } receiveValue: { [self] (searchField) in
        searchItems(searchText: searchField)
      }.store(in: &subscription)
  }

  func searchItems(searchText: String) {
    self.dataResult.loading = true
    let url = "\(API.URL)\(searchText)"
    AF.request(url,method: .get,encoding: JSONEncoding(),headers: DataService.getHeader())
      .publishData()
      .sink { _ in }receiveValue: { (response) in
        self.dataResult.loading = false
        self.dataResult.getResult(response.response,data: response.data)
        if self.dataResult.result == nil || self.dataResult.result != nil && self.dataResult.result?.count == 0{
          self.dataResult.setError(errorObj: ErrorMessage(ErrorType.Empty.rawValue))
        }
      }
      .store(in: &subscription)
  }
}

解决方法

使用 @ObservedObject 时,您的视图会在被丢弃或重新渲染时重新创建。因此您需要在 @StateObject 中使用 SearchView 而不是 @ObservedObject

此外,@ObservedObject 中不应包含 SimpleSearchModelView。它应该在您的 View 中。

@ObservedObject var monitor = NetworkMonitor()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。