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

时间:2021-04-12 09:24:28

标签: swiftui combine swiftui-navigationlink swiftui-foreach

父视图包含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)
  }
}

1 个答案:

答案 0 :(得分:0)

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

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

@ObservedObject var monitor = NetworkMonitor()