I'm working on an iPad app that's essentially a large form (with text fields, pickers, etc).
Initially I made the whole UI using @State variables just to get the UI behaviour working, now I want to transition to using @Published vars in view models, etc. I do desire bidirectional binding.
When I moved all the @State Strings to @ObservedObject and @Published the performance of typing in the text fields became very slow and choppy.
It seems worse the more I add. Performance was buttery smooth with @State, but as soon as I made them the view model @ObservedObject things went downhill.
Using Xcode 11.2.1 and iPad simulator (though it's still choppy in an iPhone simulator). 2018 MBP.
Either I'm misunderstanding the way @ObservedObject and @Published works and it's chasing it's tail or something, or there could be a problem in Combine/SwiftUI somewhere?
I've included some demo code, even half this many elements still results in a noticable choppy experience.
import SwiftUI
import Combine
struct ContentView: View {
//Slow
@ObservedObject var viewModel: ViewModel = ViewModel()
//Smooth
//@State var viewModel: ViewModel = ViewModel()
var body: some View {
Form {
Section {
Group {
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field1)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field2)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field3)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field4)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field5)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field6)
}
}
Group {
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field7)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field8)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field9)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field10)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field11)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field12)
}
}
Group {
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field13)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field14)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field15)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field16)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field17)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field18)
}
}
Group {
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field19)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field20)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field21)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field22)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field23)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field24)
}
}
Group {
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field19)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field20)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field21)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field22)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field23)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field24)
}
}
Group {
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field19)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field20)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field21)
}
HStack {
Text("Derp")
TextField("Derp", text: $viewModel.field22)
}
}
}
}
}
}
class ViewModel: ObservableObject {
@Published var field1: String = ""
@Published var field2: String = ""
@Published var field3: String = ""
@Published var field4: String = ""
@Published var field5: String = ""
@Published var field6: String = ""
@Published var field7: String = ""
@Published var field8: String = ""
@Published var field9: String = ""
@Published var field10: String = ""
@Published var field11: String = ""
@Published var field12: String = ""
@Published var field13: String = ""
@Published var field14: String = ""
@Published var field15: String = ""
@Published var field16: String = ""
@Published var field17: String = ""
@Published var field18: String = ""
@Published var field19: String = ""
@Published var field20: String = ""
@Published var field21: String = ""
@Published var field22: String = ""
@Published var field23: String = ""
@Published var field24: String = ""
}