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()
}
}