SwiftUI TextEditor - 编辑完成后保存状态
Posted
技术标签:
【中文标题】SwiftUI TextEditor - 编辑完成后保存状态【英文标题】:SwiftUI TextEditor - save the state after completion of editing 【发布时间】:2021-01-30 09:40:54 【问题描述】:问题概述
我正在构建一个笔记应用程序,并且有一个笔记编辑视图,其中一些 TextEditor 用于听取用户的输入。现在一个环境对象被传递给这个笔记编辑视图,我设计了一个保存按钮来保存更改。它运行良好,只是用户必须单击保存按钮才能更新模型。
预期行为
一旦编辑完成,文本编辑器将更新 EnvironmentObject 实例的值。不一定要点击保存按钮来保存更改。
下面是view的示例代码
struct NoteDetails: View
@EnvironmentObject var UserData: Notes
@Binding var selectedNote: SingleNote?
@Binding var selectedFolder: String?
@Binding var noteEditingMode: Bool
@State var title:String = ""
@State var updatedDate:Date = Date()
@State var content: String = ""
var id: Int?
var label: String?
@State private var wordCount: Int = 0
var body: some View
VStack(alignment: .leading)
TextEditor(text: $title)
.font(.title2)
.padding(.top)
.padding(.horizontal)
.frame(width: UIScreen.main.bounds.width, height: 50, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
Text(updatedDate, style: .date)
.font(.subheadline)
.padding(.horizontal)
Divider()
TextEditor(text: $content)
.font(.body)
.lineSpacing(15)
.padding(.horizontal)
.frame(maxHeight:.infinity)
Spacer()
下面是EnvironmentObject的edit func的示例代码
UserData.editPost(label: label!, id: id!, data: SingleNote(updateDate: Date(), title: title, body: content))
我尝试过的方法
我尝试将 onChange 修饰符添加到 TextEditor,但它会在发生任何更改时立即应用,这是不希望的。我还尝试了其他一些修饰符,例如 onDisapper 等。 用户数据有@Published var NoteList: [String: [SingleNote]]
,我尝试将 $UserData.NoteList[label][id].title 传递给 TextEditor,但也没有被接受
在互联网上没有找到合理的解决方案,所以在这里提出这个问题。提前感谢您的建议!
【问题讨论】:
【参考方案1】:我不知道编辑完成后要保存的确切含义。以下是我发现的两种可能的方法。
注意: 在下面的演示中,蓝色背景的文本显示保存的文本。
1。当用户关闭键盘时保存
解决方案:添加点击手势,让用户在TextEditor
之外点击时关闭键盘。同时拨打save()
。
代码:
struct ContentView: View
@State private var text: String = ""
@State private var savedText: String = ""
var body: some View
VStack(spacing: 20)
Text(savedText)
.frame(width: 300, height: 200, alignment: .topLeading)
.background(Color.blue)
TextEditor(text: $text)
.frame(width: 300, height: 200)
.border(Color.black, width: 1)
.onTapGesture
.onTapGesture hideKeyboardAndSave()
private func hideKeyboardAndSave()
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
save()
private func save()
savedText = text
2。在 x 秒内没有更改后保存
解决方案:使用 Combine
和 .debounce
仅在 x
秒过去且没有进一步事件后进行发布和观察。
我已将x
设置为 3。
代码:
struct ContentView: View
@State private var text: String = ""
@State private var savedText: String = ""
let detector = PassthroughSubject<Void, Never>()
let publisher: AnyPublisher<Void, Never>
init()
publisher = detector
.debounce(for: .seconds(3), scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
var body: some View
VStack(spacing: 20)
Text(savedText)
.frame(width: 300, height: 200, alignment: .topLeading)
.background(Color.blue)
TextEditor(text: $text)
.frame(width: 300, height: 200)
.border(Color.black, width: 1)
.onChange(of: text) _ in detector.send()
.onReceive(publisher) save()
private func save()
savedText = text
【讨论】:
感谢您的建议!它有很大帮助!我应该更清楚,例如,我在 iPhone 上查看 Apple 制作的 Native Notes 应用程序,每当您在便笺中键入内容时,它都会立即保存。你知道那个解决方案是什么吗?这与您的第二个解决方案相似吗? 有点上下文,对不起,这是一个子视图导航链接,如何在用户单击按钮返回时自动保存更改。它可以简化场景。 欢迎您!是的,我认为这会简化场景。保存在.onDisappear
里面对我来说可以吗?
我从来没有做过类似的事情,但看起来 Apple Notes 可能会使用与我的第二个类似的解决方案。
直观地说,onDisappear
是正确的选择,对吧?我尝试在下面添加这样的修饰符。但是它弹出了一个奇怪的错误,说 is null 所以当我点击它时 unwrap 失败。这很奇怪,因为只要选择了 id 就不能为空,并且在父导航视图中,id 已传递给该视图并且为空。 swift onDisappear(perform: UserData.NoteList[label!]![id!].title = title )
onDisappear 修饰符中的环境对象应该如何处理?你能建议吗?谢谢!以上是关于SwiftUI TextEditor - 编辑完成后保存状态的主要内容,如果未能解决你的问题,请参考以下文章
如何防止 TextEditor 在 SwiftUI 中滚动?
如何根据 TextEditor 的文本更改为 SwiftUI 视图设置动画?
SwiftUI for MacOS 中的多行 TextField/TextEditor 表单