【问题标题】:SwiftUI NavigationLink clears parent view's data when navigate to detail viewSwiftUI NavigationLink 在导航到详细视图时清除父视图的数据
【发布时间】:2021-04-12 09:24:28
【问题描述】:

父视图包含SearchBarForEach List,列表中的每个项目都包含在NavigationLink 项目中,问题是父列表。在ForEach 中点击NavigationLink 后清除它,我还为ForEach 添加了UUID(),但同样的问题发生了。我使用的是 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)
  }
}

【问题讨论】:

    标签: swiftui combine swiftui-navigationlink swiftui-foreach


    【解决方案1】:

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

    你也不应该在SimpleSearchModelView 中有@ObservedObject。它应该在您的View 中。

    @ObservedObject var monitor = NetworkMonitor()
    

    【讨论】:

    • @StateObject 仅适用于 iOS 14,我也需要 ios13 的东西
    • 我不确定,但请尝试在您的根视图中初始化您的simpleSearchMV(例如ContentView)。或者尝试使用EnvironmentObject。请注意,使用@ObservedObject 有时会导致一些意想不到的副作用,这就是他们引入@StateObject 的原因。
    • 您不应该像初始化 StateObject 一样初始化 ObservedObject。应该是从前一个视图传过来的
    猜你喜欢
    • 2021-01-07
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 2021-10-21
    • 2020-09-13
    • 2022-12-12
    • 1970-01-01
    相关资源
    最近更新 更多