親ビューには and が含ま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)
}
}