[英]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.