问题描述
父视图包含SearchBar
和ForEach
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()