Well, I'm working on a little app where I have a TextEditor element to type whatever we want. The case is, I want to keep the text on the TextEditor while switching other views, but I can't.
TextEditor before switching the view :

TextEditor after switching the view :

The code is the next one:
struct VistaDatos: View {
@State private var opinion: String = ""
var progreso : Double {
Double(opinion.count)
}
var body: some View {
VStack{
//SOME CODE HERE ...
HStack{
Text("Mi opinión...")
.font(.headline)
Image(systemName: "pencil")
.foregroundColor(.white)
.font(.headline)
}
VStack{
TextEditor(text: $opinion)
.background(.green)
.frame(width: 350, height: 250)
.background().colorMultiply(.green)
.overlay(Rectangle().stroke(Color.black, lineWidth:2))
.disableAutocorrection(true)
.onChange(of: self.opinion) { value in
if Int(opinion.count) > 150 {
self.opinion = String(value.prefix(150))
}
}
Text("Número de palabras: \(Int(progreso))/150").foregroundColor(Int(progreso) >= 100 ? .red : .white)
ProgressView(,value: progreso, total: 150) {
}.frame(width: 350, alignment: .center)
}
}.background(Color.green)
Spacer()
}
}
I have to use .onDisappear event to make it work (it seems to be on the first level stack ), but it isn't working... How can I make it work?
Thanks in advance.
CodePudding user response:
Since you say you have multiple views, that I assume may need the opinion text,
try this example code. It keeps your text in a ObservableObject,
that you can use throughout your app.
For you to do, is to code the save and retrieve
from wherever you want. In this example it is using the UserDefaults.
class StoreService: ObservableObject {
// your text
@Published var opinion = ""
// ... todo code to store your data when you are finished
func save() {
// save your data
UserDefaults.standard.set(opinion, forKey: "opinion")
}
// ... todo code to retrieve your data when the app starts again
init() {
// get your data
opinion = UserDefaults.standard.string(forKey: "opinion") ?? ""
}
}
struct ContentView: View {
@StateObject var store = StoreService() // <-- here
var body: some View {
NavigationStack {
VStack (spacing: 50) {
Text("\(store.opinion.count) characters typed")
NavigationLink("go to VistaDatos", value: "editor")
.navigationDestination(for: String.self) { str in
VistaDatos()
}
}
}.environmentObject(store) // <-- here
}
}
struct VistaDatos: View {
@EnvironmentObject var store: StoreService // <-- here
var progreso : Double {
Double(store.opinion.count)
}
var body: some View {
VStack{
//SOME CODE HERE ...
HStack{
Text("Mi opinión...").font(.headline)
Image(systemName: "pencil")
.foregroundColor(.white)
.font(.headline)
}
VStack{
TextEditor(text: $store.opinion) // <-- here
.background(.green)
.frame(width: 350, height: 250)
.background().colorMultiply(.green)
.overlay(Rectangle().stroke(Color.black, lineWidth:2))
.disableAutocorrection(true)
.onChange(of: store.opinion) { value in
if store.opinion.count > 150 {
store.opinion = String(value.prefix(150))
}
}
Text("Número de palabras: \(Int(progreso))/150").foregroundColor(Int(progreso) >= 100 ? .red : .white)
ProgressView(value: progreso, total: 150).frame(width: 350, alignment: .center)
Button("Save me") { // <-- here
store.save()
}
}
}.background(Color.green)
Spacer()
}
}
Alternatively, you could use the simple @AppStorage, like this:
struct ContentView: View {
@AppStorage("opinion") var opinion = "" // <-- here
var body: some View {
NavigationStack {
VStack (spacing: 50) {
Text("\(opinion.count) characters typed")
NavigationLink("go to VistaDatos", value: "editor")
.navigationDestination(for: String.self) { str in
VistaDatos()
}
}
}
}
}
struct VistaDatos: View {
@AppStorage("opinion") var opinion = "" // <-- here
var progreso : Double {
Double(opinion.count)
}
var body: some View {
VStack{
//SOME CODE HERE ...
HStack{
Text("Mi opinión...").font(.headline)
Image(systemName: "pencil")
.foregroundColor(.white)
.font(.headline)
}
VStack{
TextEditor(text: $opinion) // <-- here
.background(.green)
.frame(width: 350, height: 250)
.background().colorMultiply(.green)
.overlay(Rectangle().stroke(Color.black, lineWidth:2))
.disableAutocorrection(true)
.onChange(of: opinion) { value in
if opinion.count > 150 {
opinion = String(value.prefix(150))
}
}
Text("Número de palabras: \(Int(progreso))/150").foregroundColor(Int(progreso) >= 100 ? .red : .white)
ProgressView(value: progreso, total: 150).frame(width: 350, alignment: .center)
}
}.background(Color.green)
Spacer()
}
}
