簡體   English   中英

使用更新的@published 變量推送導航鏈接

[英]Push the navigation link with the updated @published variable

我在一張表中更新了已發布的 var chats 當工作表被解除(通過按鈕按下)時, MessageView導航到ChatView 我希望在ChatView中使用更新的chats ,但是現在當它第一次推送時, chats不會更新,直到你 go 返回並再次推送視圖。 有辦法繞過嗎?

getAllChats 是帶有 var chats的 observableobject

class getAllChats : ObservableObject{
    
    @Published var chats = [Chat]()
    
    @EnvironmentObject var userInfo : UserData
    
    init() {
        
        let db = Firestore.firestore()
        let currentid = Auth.auth().currentUser!.uid
        
        db.collection("users").document(currentid).getDocument { (document, err) in
            if let document = document {
                
                //all chat ids
                if let chatIDs = document.get("chats") as? [String]{
                    
                    for chatid in chatIDs{ //download chat from chat ids
                        db.collection("chats").document(chatid).getDocument { (doc, error) in
                            if let doc = doc{
                                let frienduid = doc.get("user1") as! String == currentid ? doc.get("user2") as! String : doc.get("user1") as! String
                                let friendname = doc.get("user1") as! String == currentid ? doc.get("user2_username") as! String : doc.get("user1_username") as! String
                                
                                let friend = FetchedUser.init()
                                friend.uid = frienduid
                                friend.username = friendname
                                
                                //parse msg
                                var messages: [Message] = []
                                
                                let messagesArr = doc.get("messages") as! [[String:Any]]
                                for msg in messagesArr {
                                    messages.append(Message.fromDB(object: msg))
                                }
                                
                                //create chat
                                let chat = Chat.init(friend: friend, messages: [])
                                self.chats.append(chat)
                                print(self.chats.count)
                            }
                        }
                    }
                }
            }
        }
    }
}

消息視圖

    struct MessagingView: View {
    @State var addChat = false //show search user view
    @State var showNewChat = false
   
    @State var addedUser = FetchedUser.init()

    @ObservedObject var chatsData = getAllChats()
    
    @EnvironmentObject var userInfo: UserData
    
    init(){
        UITableView.appearance().tableFooterView = UIView()
        UITableView.appearance().separatorStyle = .none
    }
    
    @ViewBuilder
    var body: some View {
        VStack{
            List(chatsData.chats, id: \.chatID){ chat in
                NavigationLink(destination: ChatView(chat: chat)) {
                    ChatCellView(chat: chat)
                }
            }
            
            //navigate to a new chat
            if !chatsData.chats.isEmpty{
            NavigationLink(destination: ChatView(chat: chatsData.chats[0]), isActive: $showNewChat){
                Text("")
            }
            }
            
        }
        .navigationBarItems(trailing: Button(action: {
                        self.addChat.toggle()
                    }, label: {
                        Image(systemName: "plus.circle.fill")
                            .font(.headline)
                    }).accentColor(.white))
                                                  
                        .sheet(isPresented: $addChat) {
                            AddChatView(addedUser: self.$addedUser, addChat: self.$addChat, showNewChat: self.$showNewChat)
                                .environmentObject(self.userInfo)
                            
        }
                    
    }
}


struct ChatCellView: View{
    var chat: Chat
    
    var body: some View{
        VStack(spacing: 0){
            HStack{
                Image(systemName: "person.crop.circle")
                    .font(.title)
                    .padding()
                
                VStack(alignment: .leading){
                    Text(chat.friend.username)
                        .font(.headline)
                    
                    HStack{
                        Text(chat.mostRecentMessage()?.body ?? "Tap to chat")
                            .font(.body)
                            .padding(.trailing, 10)
                        
                        Spacer()
                    }
                }
                
                Circle()
                    .fill(isUnread() ? Color.navIconColor : Color.clear)
                    .frame(width: 12, height: 12)
                
                Spacer()
            }
        }
    }
    
    func isUnread() -> Bool{
        if let mostRecentMessage = chat.mostRecentMessage() {
            return !mostRecentMessage.hasRead && mostRecentMessage.recipient == "user"
        }
        return false
    }
    
}

聊天視圖

struct ChatView: View{
    
    var chat: Chat

    @State var write = ""
    
    var body: some View {
        VStack {
            List(chat.messages) { i in
                ListMessage(msg: i.body, sentFromUser: i.sender == "user")
            }
            .navigationBarTitle(
                Text(chat.friend.username), displayMode: .inline)
                .accentColor(.white)
           
            
            HStack {
                TextField("message...",text: self.$write).padding(10)
                    .background(Color(red: 233.0/255, green: 234.0/255, blue: 243.0/255))
                    .cornerRadius(25)
                
                Button(action: {
                    if self.write.count > 0 {
                        //self.message.addInfo(msg: self.write, user: self.name, image: self.image)
                        self.write = ""
                    } else {
                        
                    }
                }) {
                    Image(systemName: "paperplane.fill").font(.system(size: 20))
                        .foregroundColor((self.write.count > 0) ? Color.navIconColor : Color.gray)
                        .rotationEffect(.degrees(50))
                    
                }
            }.padding()
        }.padding(.top)
         .modifier(AdaptsToKeyboard())
    }
}

struct ListMessage : View {
    
    var msg = ""
    
    var sentFromUser = false
    
    var body: some View {
        
        HStack {
            if sentFromUser {
                Spacer()
                
                HStack {
                    Text(msg).padding(10).background(Color.secondary)
                        .cornerRadius(18)
                        .foregroundColor(.white)
                    
                    
                }
            } else {
                HStack {
                    
                    Text(msg).padding(10).background(Color.titleBarColor)
                        .cornerRadius(28)
                        .foregroundColor(.white)
                    
                }
                Spacer()
            }
        }
    }
}

我認為鏈接切換得太早了,所以不要通過在工作表中綁定來激活鏈接,而是在工作表被解除后嘗試激活它

這是一種方法(粗糙,因為提供的快照不可測試)

.sheet(isPresented: $addChat, 
       onDismiss: { self.$showNewChat }) {  // << here
    
    // refactor AddChatView to remove dependency on showNewChat
    AddChatView(addedUser: self.$addedUser, addChat: self.$addChat)
        .environmentObject(self.userInfo)
}

所以問題是你想用 object chat中的新聊天更新 chatView

而且您不是在ChatView內觀察chat ,而是在Messageview內觀察聊天,因此它無法在ChatView內更新。 這就是當您返回messageView時它會更新的原因

所以您需要將您的聊天轉換為 ObservedObject 以列出其發布者。

struct ChatView: View{
    
    @ObservedObject var chat: Chat

    @State var write = ""
...................
............

}

並且您還需要將Chat (individual) 修改為 class 中的 ObservableObject。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM