0

我在工作表中更新了已发布的 var chats。当工作表被解除(通过按钮按下)时,MessageView导航到ChatView. 我希望在 中使用更新chatsChatView内容,但现在第一次推送时,chats不会更新,直到您返回并再次推送视图。有办法绕过吗?

getAllChats 是带有 var 的 observableobjectchats

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()
            }
        }
    }
}
4

2 回答 2

0

所以问题是你想用对象中的新聊天更新chatViewchat

而且你不是chat在里面观察ChatView,而是在里面观察聊天 Messageview,所以里面不能更新ChatView。这就是您返回时更新的原因messageView

所以您需要将您的聊天转换为 ObservedObject 以列出其发布者。

struct ChatView: View{
    
    @ObservedObject var chat: Chat

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

}

并且您还需要将Chat(个人)修改为其类中的 ObservableObject 。

于 2020-07-08T11:24:24.397 回答
0

我认为链接切换得太早了,所以不要通过在工作表中绑定来激活链接,而是在工作表被解除后尝试激活它

这是一种方法(粗糙,因为提供的快照不可测试)

.sheet(isPresented: $addChat, 
       onDismiss: { self.$showNewChat }) {  // << here
    
    // refactor AddChatView to remove dependency on showNewChat
    AddChatView(addedUser: self.$addedUser, addChat: self.$addChat)
        .environmentObject(self.userInfo)
}
于 2020-07-08T03:53:05.190 回答