NavigationLink 在文本字段值更新到 Firestore 后关闭
NavigationLink Dismisses after Textfield Value is Updated to Firestore
我正在尝试制作类似于 iOS 笔记应用程序但用于日记的东西;基本上,我希望有一个日记条目单元格列表,用户可以滚动浏览每个单元格,在单击用户可以查看和编辑其日记条目的位置后,每个单元格都会显示一个详细视图。更新工作正常,唯一的问题是 JournalDetailView
在 updateEntry()
被调用后(在用户点击“完成”按钮后)自行消失。我猜这是因为 updateEntry()
强制重新加载视图,但我不确定如何解决这个问题。
这是模型:
struct JournalEntry: Identifiable, Hashable, Codable {
@DocumentID var id: String? = UUID().uuidString
@ServerTimestamp var date: Timestamp?
var text: String
var userId: String?
}
查看代码如下:
struct JournalCellView: View {
@ObservedObject var vm: JournalViewModel
@Binding var addButtonTapped: Bool
@State var showDetail = false
@State var entry: JournalEntry
var body: some View {
NavigationLink(destination: JournalDetailView(vm: vm, entry: $entry, text: entry.text), isActive: $showDetail, label: {
VStack {
HStack {
Text(entry.date!.dateValue(), style: .date)
.fontWeight(.bold)
.font(.system(size: 18))
.foregroundColor(.black)
.padding(.bottom, 3)
Spacer()
}
HStack {
Text(entry.text)
.font(.system(size: 14))
.foregroundColor(.secondary)
.lineLimit(1)
Spacer()
}
}.padding()
.background(RoundedRectangle(cornerRadius: 18).foregroundColor(.white))
.padding(.vertical, 4)
.onTapGesture {
showDetail = true
}
.onAppear {
if addButtonTapped {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
showDetail = true
}
addButtonTapped = false
}
}
})
}
}
struct JournalDetailView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var vm: JournalViewModel
@Binding var entry: JournalEntry
@State var text: String
@State var isTyping = false
var body: some View {
VStack {
HStack {
Button(action: {
presentationMode.wrappedValue.dismiss()
}, label: { Image(systemName: "chevron.left").foregroundColor(.burgundy) })
Spacer()
if isTyping {
Button(action: {
endEditing()
updateEntry()
isTyping = false
}) {
Text("Done")
.foregroundColor(.burgundy)
}
} else {
Text("")
}
}.padding(.vertical)
Text(entry.date!.dateValue(), style: .date)
TextEditor(text: $text)
.onTapGesture {
isTyping = true
}
Spacer()
}.padding()
.navigationBarHidden(true)
}
func updateEntry() {
vm.updateJournalEntry(docID: entry.id!, date: entry.date!, text: text)
}
}
这里是updateJournalEntry()
:
func updateJournalEntry(docID: String, date: Timestamp, text: String) {
db.collection("journals").document(docID
).updateData(["date": date, "text": text, "userId": Auth.auth().currentUser!.uid])
}
我设法通过仅在使用 .onDisappear
和 .onReceive
自然关闭视图后进行更新来解决这个问题。不是最干净的解决方案,但它有效。如果有人有其他建议,请贡献!
.onDisappear {
updateEntry()
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
updateEntry()
}
我正在尝试制作类似于 iOS 笔记应用程序但用于日记的东西;基本上,我希望有一个日记条目单元格列表,用户可以滚动浏览每个单元格,在单击用户可以查看和编辑其日记条目的位置后,每个单元格都会显示一个详细视图。更新工作正常,唯一的问题是 JournalDetailView
在 updateEntry()
被调用后(在用户点击“完成”按钮后)自行消失。我猜这是因为 updateEntry()
强制重新加载视图,但我不确定如何解决这个问题。
这是模型:
struct JournalEntry: Identifiable, Hashable, Codable {
@DocumentID var id: String? = UUID().uuidString
@ServerTimestamp var date: Timestamp?
var text: String
var userId: String?
}
查看代码如下:
struct JournalCellView: View {
@ObservedObject var vm: JournalViewModel
@Binding var addButtonTapped: Bool
@State var showDetail = false
@State var entry: JournalEntry
var body: some View {
NavigationLink(destination: JournalDetailView(vm: vm, entry: $entry, text: entry.text), isActive: $showDetail, label: {
VStack {
HStack {
Text(entry.date!.dateValue(), style: .date)
.fontWeight(.bold)
.font(.system(size: 18))
.foregroundColor(.black)
.padding(.bottom, 3)
Spacer()
}
HStack {
Text(entry.text)
.font(.system(size: 14))
.foregroundColor(.secondary)
.lineLimit(1)
Spacer()
}
}.padding()
.background(RoundedRectangle(cornerRadius: 18).foregroundColor(.white))
.padding(.vertical, 4)
.onTapGesture {
showDetail = true
}
.onAppear {
if addButtonTapped {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
showDetail = true
}
addButtonTapped = false
}
}
})
}
}
struct JournalDetailView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var vm: JournalViewModel
@Binding var entry: JournalEntry
@State var text: String
@State var isTyping = false
var body: some View {
VStack {
HStack {
Button(action: {
presentationMode.wrappedValue.dismiss()
}, label: { Image(systemName: "chevron.left").foregroundColor(.burgundy) })
Spacer()
if isTyping {
Button(action: {
endEditing()
updateEntry()
isTyping = false
}) {
Text("Done")
.foregroundColor(.burgundy)
}
} else {
Text("")
}
}.padding(.vertical)
Text(entry.date!.dateValue(), style: .date)
TextEditor(text: $text)
.onTapGesture {
isTyping = true
}
Spacer()
}.padding()
.navigationBarHidden(true)
}
func updateEntry() {
vm.updateJournalEntry(docID: entry.id!, date: entry.date!, text: text)
}
}
这里是updateJournalEntry()
:
func updateJournalEntry(docID: String, date: Timestamp, text: String) {
db.collection("journals").document(docID
).updateData(["date": date, "text": text, "userId": Auth.auth().currentUser!.uid])
}
我设法通过仅在使用 .onDisappear
和 .onReceive
自然关闭视图后进行更新来解决这个问题。不是最干净的解决方案,但它有效。如果有人有其他建议,请贡献!
.onDisappear {
updateEntry()
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
updateEntry()
}