I have been trying to change the offset value of an object in SwiftUI, but can't quite get it to work. I feel like there's something basic I'm missing here.
Below is the main SwiftUI code. I am trying to change the offset value of each card in a stack as the user swipes. However, on line with "user.offset = value.translation.width", I get the error "Cannot assign to property: 'user' is a 'let' constant". I think I understand that that is because you are not actually able to change the object you are iterating through with a ForEach loop. However, I'm struggling to find a workaround.
import SwiftUI
import Kingfisher
struct GroupSessionView: View {
@ObservedObject var userViewModel = ExploreUsersViewModel()
var body: some View {
VStack(spacing: 10) {
ZStack {
ForEach(Array(zip(userViewModel.userCards.indices, userViewModel.userCards)), id: \.0) { index, user in
HStack {
KFImage(URL(string: user.image))
}
.zIndex(Double(userViewModel.users.count - index))
.offset(x: 0)
.gesture(DragGesture().onChanged({ value in
withAnimation {
user.offset = value.translation.width
}
}).onEnded({ (value) in
withAnimation {
user.offset = 0
}
}))
}
}
Spacer()
}
}
}
And here is the view model I am working with to produce the userCards data.
class ExploreUsersViewModel: ObservableObject {
@Published var users = [User]()
@Published var userCards = [UserCard]()
let service = UserService()
init() {
fetchUsers()
getCards()
}
func fetchUsers() {
service.fetchUsers { users in
self.users = users
print("Users are \(users)")
}
}
func getCards() {
service.fetchUsers { users in
for user in users {
self.userCards.append(UserCard(id: NSUUID().uuidString, image: user.profileImageUrl, fullName: user.fullname, offset: 0))
}
}
}
}
CodePudding user response:
In ForEach
(as well as forEach
) all index variables are constants.
But as you have the index the solution is pretty easy: Modify the item in the array directly
userViewModel.userCards[index].offset = value.translation.width