Reputation: 2471
***** I have updated My Model and ViewModel *****
I have a Card View and an array. I'm looping over that array to create an equal number of cards. I can transition and animate the first creation of card using the .onAppear
method. I have two buttons to remove and add array items in a model. When I add and remove from an array using withAnimation
I'm getting default fading transition. However I want transition(.scale)
. How do I get it?
Here is the Model:
struct Model {
var dataArray : Array<Model.Data> = [Data(), Data(), Data()]
mutating func addToArray() {
dataArray.append(Data())
}
mutating func removeFromArray() {
dataArray.remove(at: 0)
}
struct Data : Identifiable {
var id = UUID()
}
}
Here is my ViewModel:
class ViewModelTest : ObservableObject {
@Published var model = Model()
var dataArray : Array<Model.Data> {
model.dataArray
}
func addToArray() {
model.addToArray()
}
func removeFromArray() {
model.removeFromArray()
}
}
Here is my View :
struct ContentView: View {
@ObservedObject var viewModel = ViewModelTest()
@State private var isLoading = false
var body: some View {
VStack {
HStack {
ForEach(viewModel.dataArray, id: \.self) { _ in
Group {
if self.isLoading {
Color.red
.frame(width: 100, height: 170)
.transition(.scale)
}
}
}
.animation(.easeInOut(duration: 5))
.onAppear {
self.isLoading = true
}
HStack {
Button(action: {
withAnimation(.easeInOut(duration: 1)) {
self.viewModel.addToArray()
}
}) {
Text("add")
}
Button(action: {
withAnimation(.easeInOut(duration: 1)) {
self.viewModel.removeFromArray()
}
}) {
Text("remove")
}
}
}
}
}
I'm getting the following error: Generic struct ForEach
requires that Model.Data
conform to Hashable
Upvotes: 1
Views: 221
Reputation: 257719
Here is a possible solution. (Note: your dataArray
have to contain unique values, otherwise you should find a way to make them uniquely identified)
Tested with Xcode 12 / iOS 14
struct ContentView: View {
@ObservedObject var viewModel = ViewModelTest()
@State private var isLoading = false
var body: some View {
VStack {
HStack {
ForEach(viewModel.model.dataArray, id: \.self) { _ in
if self.isLoading {
Color.red
.frame(width: 100, height: 170)
.transition(.scale)
}
}
}
.animation(.easeInOut(duration: 1))
.onAppear {
self.isLoading = true
}
HStack {
Button(action: {
self.viewModel.addToArray()
}) {
Text("add")
}
Button(action: {
self.viewModel.removeFromArray()
}) {
Text("remove")
}
}
}
}
}
Update: for SwiftUI 1.0 use the following (tested with Xcode 11.4 / iOS 13.4)
ForEach(viewModel.model.dataArray, id: \.self) { _ in
Group {
if self.isLoading {
Color.red
.frame(width: 100, height: 170)
.transition(.scale)
}}
}
Upvotes: 2