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