Reputation: 3092
So I'm fairly new to SwiftUI & Swift (Javascript background) and I am going through the SwiftUI tutorial on Apple website.
When you get through the first section, you'll end up with LandmarkDetail.swift body ends up something like this:
var body: some View {
VStack {
MapView(coordinate: landmark.locationCoordinate)
.edgesIgnoringSafeArea(.top)
.frame(height: 300)
CircleImage(image: landmark.image)
.offset(x: 0, y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
HStack {
Text(landmark.name)
.font(.title)
Button(action: {
self.userData.landmarks[self.landmarkIndex].isFavorite.toggle()
}, label: {
if (self.userData.landmarks[self.landmarkIndex].isFavorite) {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
}
else {
Image(systemName: "star")
.foregroundColor(.gray)
}
})
}
HStack(alignment: .top) {
Text(landmark.park)
.font(.subheadline)
Spacer()
Text(landmark.state)
.font(.subheadline)
}
}
.padding()
Spacer()
}
.navigationBarTitle(Text(landmark.name), displayMode: .inline)
}
All good. So I decide to make some small incremental changes just to test the language. I noticed self.userData.landmarks[self.landmarkIndex]
is used twice so I simply added that as a variable within the body and had the view return explicitly.
var userDataLandmark: Landmark = self.userData.landmarks[self.landmarkIndex]
return VStack {
No big deal. Then I replaced the repeating landmark:
Button(action: {
userDataLandmark.isFavorite.toggle()
}, label: {
if (userDataLandmark.isFavorite) {
Image(systemName: "star.fill")
Everything looked fine on the surface, but the toggle()
functionality no longer works. Generally assuming this is some referencing/pointer stuff but If anyone could explain why that'd be great.
Upvotes: 0
Views: 59
Reputation: 49590
When you did:
var userDataLandmark: Landmark = self.userData.landmarks[self.landmarkIndex]
you created a copy of self.userData.landmarks[self.landmarkIndex]
, because Landmark
is a value-type (a struct
).
Now, when you do:
userDataLandmark.isFavorite.toggle()
you're toggling the copy. So, it doesn't change the .landmarks
property of the observed environment variable userData
, which is what would have caused the view's body to be recomputed.
Upvotes: 3