无法在 SwiftUI 中获取搜索列表所选项目 id

问题描述 投票:0回答:1

我有一个用于显示所有列表的 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)
    }
}
}
swift list button swiftui onchange
1个回答
0
投票

您可以尝试这种替代方法,使用不带范围和索引的

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)
 }
© www.soinside.com 2019 - 2024. All rights reserved.