SwiftUI TextEditor-编辑完成后保存状态 问题概述

SwiftUI TextEditor-编辑完成后保存状态 问题概述,swiftui,text-editor,Swiftui,Text Editor,我正在开发一个笔记应用程序,有一个笔记编辑视图,其中一些文本编辑器用于听取用户的输入。现在,一个环境对象被传递到ThisNoteEditing视图,我设计了一个save按钮来保存更改。除了用户必须单击“保存”按钮来更新模型之外,它工作得很好 预期行为 编辑完成后,文本编辑器将更新EnvironmentObject实例的值。不必单击“保存”按钮来保存更改 下面是视图的示例代码 structNoteDetails:视图{ @EnvironmentObject var UserData:Notes @

我正在开发一个笔记应用程序,有一个笔记编辑视图,其中一些文本编辑器用于听取用户的输入。现在,一个环境对象被传递到ThisNoteEditing视图,我设计了一个save按钮来保存更改。除了用户必须单击“保存”按钮来更新模型之外,它工作得很好

预期行为 编辑完成后,文本编辑器将更新EnvironmentObject实例的值。不必单击“保存”按钮来保存更改

下面是视图的示例代码
structNoteDetails:视图{
@EnvironmentObject var UserData:Notes
@绑定变量selectedNote:SingleNote?
@绑定变量selectedFolder:字符串?
@绑定变量noteEditingMode:Bool
@状态变量标题:String=“”
@状态变量updateDate:Date=Date()
@状态变量内容:String=“”
变量id:Int?
变量标签:字符串?
@国家私有变量字计数:Int=0
var body:一些观点{
VStack(对齐:。前导){
文本编辑器(文本:$title)
.font(.title2)
.padding(.top)
.padding(.卧式)
.frame(宽度:UIScreen.main.bounds.width,高度:50,对齐:/*@START\u MENU\u TOKEN@*/.center/*@END\u MENU\u TOKEN@*/)
文本(更新日期,样式:。日期)
.font(.subheadline)
.padding(.卧式)
分隔器()
文本编辑器(文本:$content)
.font(.body)
.线间距(15)
.padding(.卧式)
.frame(最大高度:。无穷大)
垫片()
}
}
}
下面是EnvironmentObject的edit func的示例代码
UserData.editPost(标签:label!,id:id!,数据:SingleNote(updateDate:Date(),title:title,body:content))
我试过的方法
  • 我试图向TextEditor添加一个onChange修饰符,但一旦发生任何更改,它就会立即应用,这是不需要的。我还尝试了其他一些修改器,如onDisapper等
  • 用户数据已发布var NoteList:[String:[SingleNote]],我试图将$UserData.NoteList[label][id]。标题传递到文本编辑器,但也未被接受

在互联网上没有找到合理的解决方案,所以在这里提出这个问题。提前感谢您的建议

我不知道编辑完成后您要保存什么。以下是我发现的两种可能的方法

注: 在以下演示中,蓝色背景的文本将显示保存的文本

1.当用户关闭键盘时保存 解决方案:添加一个点击手势,让用户在点击
文本编辑器
外部时关闭键盘。同时调用
save()

代码:

2.在x秒内无更改后保存 解决方案:使用
.debounce
组合,仅在
x
秒后发布并观察,无进一步事件发生

我已将
x
设置为3

代码:

struct ContentView:View{
@国家私有变量文本:String=“”
@状态私有变量savedText:String=“”
let detector=PassthroughSubject()
让发布者:AnyPublisher
init(){
发布者=检测器
.debounce(用于:。秒(3),调度程序:DispatchQueue.main)
.删除任何发布者()
}
var body:一些观点{
VStack(间距:20){
文本(保存的文本)
.框架(宽度:300,高度:200,对齐方式:。顶部引导)
.背景(颜色.蓝色)
文本编辑器(文本:$text)
.框架(宽:300,高:200)
.边框(颜色.黑色,宽度:1)
.onChange(of:text){indetector.send()}
.onReceive(发布服务器){save()}
}
}
私有函数保存(){
savedText=文本
}
}

谢谢您的建议!这很有帮助!!我应该更清楚一些,例如,我正在看iPhone上苹果制造的原生Notes应用程序,每当你在便笺中键入内容时,它会立即保存。你知道那个解决方案是什么吗?这与您的第二个解决方案类似吗?有点上下文,对不起,这是一个子视图导航链接,当用户单击按钮返回时,如何自动保存更改。它可以简化场景。欢迎光临!是的,我认为这将简化场景。在
.onDisappear
内部保存对我来说很好?我从来没有做过这样的事情,但看起来Apple Notes可能会使用与我的第二个类似的解决方案。直观地说,
onDisappear
是一种方法,对吗?我尝试添加一个如下所示的修改器。但它弹出了一个奇怪的错误,说是空的,所以当我点击它时,展开失败了。这很奇怪,因为只要选中id,它就不能为null,并且在父导航视图中,id已传递给此视图,并且为null<代码>swift onDisappear(执行:{UserData.NoteList[label!]![id!].title=title})如何处理onDisappear修改器中的环境对象?你能提出建议吗?谢谢
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
    }
}
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
    }
}