In the example following, I'm calling an instance method of a View using the method directly (saveTitle), and via a pointer to that method (saveAction).
When calling the method, I am passing in the current value of the title variable. When I call it directly, the current value matches the value inside the method. When I call it via a pointer to the method, the value inside is the value it was when the struct was first instantiated.
It is almost like there is a new instance of the Struct being created, but without the init method being called a second time.
I suspect this has something to do with how SwiftUI handles @State modifiers, but I'm hoping someone out there will have a better understanding, and be able to enlighten me a bit.
Thanks much for your consideration :)
import SwiftUI
struct EditContentView: View {
@Binding var isPresented: Bool
@State var title: String
var saveAction: ((String) -> Void)?
var body: some View {
TextField("new title", text: $title)
Button("save") {
print("calling saveText")
// this call works as expected, the title inside the saveTitle method is the same as here
saveTitle(title)
print("now calling saveAction, a pointer to saveTitle")
// with this call the title inside the method is different than the passed in title here
// even though they are theoretically the same member of the same instance
saveAction!(title)
isPresented = false
}
}
init(isPresented: Binding<Bool>, title: String) {
print("this method only gets called once")
self._isPresented = isPresented
self._title = State(initialValue: title)
saveAction = saveTitle
}
func saveTitle(_ expected: String) {
if (expected == title) {
print("the title inside this method is the same as before the call")
}
else {
print("expected: \(expected), but got: \(title)")
}
}
}
struct ContentView: View {
@State var title = "Change me"
@State var showingEdit = false
var body: some View {
Text(title)
.onTapGesture { showingEdit.toggle() }
.sheet(isPresented: $showingEdit) {
EditContentView(isPresented: $showingEdit, title: title)
}
}
}