[英]Push the navigation link with the updated @published variable
I updated the published var chats
in a sheet.我在一张表中更新了已发布的 var
chats
。 And when the sheet is dismissed (by button press), the MessageView
navigates to ChatView
.当工作表被解除(通过按钮按下)时,
MessageView
导航到ChatView
。 I hope to use that updated chats
in the ChatView
, but now when it's first pushed, chats
isn't updated, until you go back and push the view again.我希望在
ChatView
中使用更新的chats
,但是现在当它第一次推送时, chats
不会更新,直到你 go 返回并再次推送视图。 Is there a way to get around?有办法绕过吗?
getAllChats is the observableobject with var chats
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)
}
}
}
}
}
}
}
}
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()
}
}
}
}
I assume the link is toggled too early, so instead of activate link by binding in sheet, try to activate it after sheet got dismissed我认为链接切换得太早了,所以不要通过在工作表中绑定来激活链接,而是在工作表被解除后尝试激活它
Here is a way (scratchy, as provided snapshot is not testable)这是一种方法(粗糙,因为提供的快照不可测试)
.sheet(isPresented: $addChat,
onDismiss: { self.$showNewChat }) { // << here
// refactor AddChatView to remove dependency on showNewChat
AddChatView(addedUser: self.$addedUser, addChat: self.$addChat)
.environmentObject(self.userInfo)
}
So the problem is you want to update the chatView with new chats which is in object chat
所以问题是你想用 object
chat
中的新聊天更新 chatView
And you are not observing chat
inside ChatView
, but you are observing chat inside Messageview
, so it cannot update inside ChatView
.而且您不是在
ChatView
内观察chat
,而是在Messageview
内观察聊天,因此它无法在ChatView
内更新。 That's th reason its updating when you are going back to messageView
这就是当您返回
messageView
时它会更新的原因
so you need to convert your chat to a ObservedObject to listed its publisher.所以您需要将您的聊天转换为 ObservedObject 以列出其发布者。
struct ChatView: View{
@ObservedObject var chat: Chat
@State var write = ""
...................
............
}
and also you need to modify Chat
(individual) to be a ObservableObject in its class.并且您还需要将
Chat
(individual) 修改为 class 中的 ObservableObject。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.