使用更新的@published变量推送导航链接

时间:2020-07-07 20:59:40

标签: ios swift swiftui swiftui-navigationlink observableobject

我在工作表中更新了已发布的变量chats。并且,当关闭工作表(通过按按钮)时,MessageView导航到ChatView。我希望在chats中使用更新后的ChatView,但是现在第一次推送时,chats不会更新,直到您返回并再次推送视图。有办法解决吗?

getAllChats是带有变量chats的可观察对象

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

MessageView

    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
    }
    
}

ChatView

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

2 个答案:

答案 0 :(得分:0)

我认为链接切换得太早了,所以与其通过在工作表中绑定来激活链接,不如在工作表被解散后尝试激活它。

这是一种方法(如果无法测试快照,则会产生混乱)

else:

答案 1 :(得分:0)

所以问题是您要使用新的聊天记录更新chatView 对象chat

您并没有在chat内观察ChatView,而是在Messageview内观察了聊天,因此无法在ChatView内进行更新。这就是为什么当您回到messageView

时会对其进行更新的原因

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

struct ChatView: View{
    
    @ObservedObject var chat: Chat

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

}

,还需要将Chat(单独)修改为其类中的ObservableObject。