我有一个用于显示所有列表的 API 和另一个用于显示搜索词列表的 API,但从所有列表中我得到
selectedDataID
但从搜索列表中选定的项目没有得到 selectedDataID
。如何到达那里
代码:使用此代码,我能够显示列表,也能够显示搜索词列表,但是在搜索时,如果我单击列表中的任何单元格,那么它会在
selectedDataID
中给出nil,但我可以转到SentAndInboxChatView,为什么?如何获得selectedDataID in search list as well
struct MessageListView: View {
@StateObject private var viewModel = AllMessagesListViewModel()
@State private var selectedDataID: String?
@State var id: String = ""
var body: some View {
ZStack {
Color.hexF4F4FC
.ignoresSafeArea()
VStack(spacing: 0) {
List {
if viewModel.allMesgs.isEmpty {
Text("No records found")
}else{
ForEach(0..<viewModel.allMesgs.count, id: \.self) { ind in
Button {
selectedDataID = viewModel.allMesgs[ind].id
gotoChat = true
} label: {
messageView(user: viewModel.allMesgs[ind])
}
if ind == viewModel.allMesgs.count - 1 {
Spacer(minLength: 30)
}
}
.padding(.top, 10)
}
}
.navigationDestination(isPresented: $gotoChat) {
SentAndInboxChatView(idInbox: selectedDataID ?? "", messageType: MessageType.Inbox.rawValue)
.toolbar(.hidden, for: .navigationBar)
}
.listStyle(.plain)
}
.onAppear {
viewModel.fetchAllMessages(id: id) { status in
}
}
Spacer()
}
}
private var searchFieldView: some View {
ZStack {
Rectangle()
.fill(Color.white)
.cornerRadius(10)
HStack {
Image(systemName: "magnifyingglass").foregroundColor(.gray)
.padding(.leading, 6)
TextField("Search", text: $searchText)
.onChange(of: searchText) { newValue in
if newValue.count >= 3 {
viewModel.fetchAllMessagesSearch(id: id, Query: newValue, showHud: false) { status in
}
print("selectedDataID.... \(selectedDataID) ")
}
else{
viewModel.fetchAllMessages(id: id, showHud: false) { status in
}
}
}
Spacer()
Button(action: {
searchText = ""
viewModel.fetchAllMessages(id: id) { status in
}
showingSearchField = false
}) {
Image(systemName: "xmark.circle.fill")
.foregroundColor(.gray)
.padding(8)
}
}
.padding(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8))
}
}
}
o/p:
selectedDataID ....无
这是我在 AllMessagesListViewModel 中的两个 API 服务调用
@MainActor class AllMessagesListViewModel: ObservableObject {
@Published var allMesgs: [AllMessage] = []
@Published var senderDtl: SenderDTL?
func fetchAllMessages(id: String, showHud: Bool = true, _ completion: @escaping StatusCompletion) {
if APIManager.shared.isConnectedToInternet {
let url = APIEndPoint.messageFrom
let params: [String: Any] = [
"ID": id
]
APIManager.shared.callDecodableApiRequest(with: url, method: .get, params: params, showHud: showHud) { (statusCode, error, model: AllMessagesModel?) in
if statusCode.isSuccess {
self.senderDtl = model?.senderDTL
self.allMesgs = model?.allMessages ?? []
completion(true)
} else {
showErrorToast(message: K.Msgs.error)
completion(false)
}
}
} else {
showInfoToast(message: K.Msgs.noInternet)
completion(false)
}
}
func fetchAllMessagesSearch(id: String, Query: String, showHud: Bool = true, _ completion: @escaping StatusCompletion) {
if APIManager.shared.isConnectedToInternet {
let url = APIEndPoint.messageFromSearch
let params: [String: Any] = [
"ID": id,
"Query": Query
]
APIManager.shared.callDecodableApiRequest(with: url, method: .get, params: params, showHud: showHud) { (statusCode, error, model: AllMessagesModel?) in
if statusCode.isSuccess {
self.senderDtl = model?.senderDTL
self.allMesgs = model?.allMessages ?? []
completion(true)
} else {
showErrorToast(message: K.Msgs.error)
completion(false)
}
}
} else {
showInfoToast(message: K.Msgs.noInternet)
completion(false)
}
}
}
您可以尝试这种替代方法,使用不带范围和索引的
ForEach
,
使用 NavigationLink
代替 Button
,并使用不同的
navigationDestination
,如:
List {
if viewModel.allMesgs.isEmpty {
Text("No records found")
} else {
ForEach(viewModel.allMesgs, id: \.self) { msg in
NavigationLink(value: msg.id) {
messageView(user: msg)
}
if viewModel.allMesgs.last == msg {
Spacer(minLength: 30)
}
}
.padding(.top, 10)
}
}
.navigationDestination(for: String.self) { itemId in
SentAndInboxChatView(idInbox: itemId, messageType: MessageType.Inbox.rawValue)
.toolbar(.hidden, for: .navigationBar)
}