I'm currently struggling with my SwiftUI app due to bugs in IOS14.3.
I have my data in an environmental object
and normally I would populate e.g. textfields via the onAppear function and @State
variables of views. However in the new feature I'd like to use a tabview
and here the onAppear
/ onDisappear
functions go crazy as described e.g. here: SwiftUI PageTabView in iOS14.2 will Recall ChildView onAppear method Many times in the current IOS version.
I've thought of a workaround and tried to use the variables from the environmental object
directly in the textfield
but that's not compatible with my dynamic array as I get an index out of range error when I delete the entries.
Therefore I would be very grateful if anyone of you has a suggestion on how I could handle:
- The population / saving of the changes once the user swipes to the next view
- How to avoid the index out of range issue
Is there a better way on how to do it than I've done it currently? It somehow doesn't feel like the easies way.
Here's my code:
Model
struct Example: Codable {
var id: String = UUID().uuidString
var name: String
}
ViewModel
class DBhandler: ObservableObject {
@Published var examples: [Example] = [Example(name: "Test1"), Example(name: "Test2")]
}
View
struct ContentView: View {
@EnvironmentObject var dbhandler: DBhandler
@State var selectedTab : Int = 0
var body: some View {
VStack{
TabView(selection: $selectedTab){
ForEach(dbhandler.examples.indices, id: .self) {exampleIndex in
SubView(exampleIndex: exampleIndex).tag(exampleIndex)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
}
}
struct SubView: View {
@EnvironmentObject var dbhandler: DBhandler
@State private var inputText : String = ""
let exampleIndex : Int
var body: some View {
//If uncommented it just hides the Index out of range error which occurs anyway
// if exampleIndex < dbhandler.examples.count {
VStack{
Text(dbhandler.examples[exampleIndex].name)
//Option 1
TextField(inputText, text: $inputText)
//Option 2
TextField(dbhandler.examples[exampleIndex].name, text: $dbhandler.examples[exampleIndex].name)
Button(action: {
dbhandler.examples.remove(at: exampleIndex)
}, label: {
Text("Delete entry: (dbhandler.examples[exampleIndex].name)")
})
}
.onAppear(perform: {
print("On Appear called")
//Get data
inputText = dbhandler.examples[exampleIndex].name
})
.onDisappear(perform: {
print("On Disappear called")
//Save data
dbhandler.examples[exampleIndex].name = inputText
})
// }
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…