0

I apply ".animation (.easeIn)" but it is deprecated. tells me: animation 'has been deprecated in iOS 15.0: use instead with Animation or animation (: value :), but animation (: value :) I don't know which value I need to pass. I can't create animations that start slowly. Can you please help me understand how I can properly use animation (_: value :) to make animation work? I have to create the animation that when I move the slider, the images slowly recompose in space according to how much they are enlarged or reduced. thank you.

'''

import SwiftUI

struct GalleryView: View {
    // MARK: - PROPERTIES
    
    @State private var selectedAnimal: String = "lion"
    
    
    let animals: [Animal] = Bundle.main.decode("animals.json")
    let haptics = UIImpactFeedbackGenerator(style: .medium)
    
    @State private var gridLayout: [GridItem] = [GridItem(.flexible())]
    @State private var gridColumn: Double = 3.0
    
    func gridSwitch() {
        gridLayout = Array(repeating: .init(.flexible()), count: Int(gridColumn))
    }
    
    // MARK: - BODY
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {

            VStack(alignment: .center, spacing: 30) {
                // MARK: - IMAGE
                
                Image(selectedAnimal)
                    .resizable()
                    .scaledToFit()
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.white, lineWidth: 8))
                
                // MARK: - SLIDER
                
                Slider(value: $gridColumn, in: 2...4, step: 1) // se aumento il valore nello slider ci saranno più sezioni
                    .padding(.horizontal)
                    .onChange(of: gridColumn, perform: { value in
                        gridSwitch()
                    })
                
                // MARK: - GRID
                LazyVGrid(columns: gridLayout, alignment: .center, spacing: 10) {
                    ForEach(animals) { item in
                        Image(item.image)
                            .resizable()
                            .scaledToFit()
                            .clipShape(Circle())
                            .overlay(Circle().stroke(Color.white, lineWidth: 1))
                            .onTapGesture {
                            selectedAnimal = item.image
                                haptics.impactOccurred()
                        }
                        
                    } //: LOOP

                } //: GRID
                .animation(.easeIn) 
                .onAppear(perform: {
                    gridSwitch()
                })
            } //: VSTACK
            .padding(.horizontal, 10)
            .padding(.vertical,50)
        } //: SCROLL
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(MotionAnimationView())
    }
}

// MARK: - PREVIEW

struct GalleryView_Previews: PreviewProvider {
    static var previews: some View {
        GalleryView()
    }
}
  • Does this answer your question? [How to replace deprecated .animation() in SwiftUI?](https://stackoverflow.com/questions/69443588/how-to-replace-deprecated-animation-in-swiftui) – stackich Apr 09 '23 at 00:35

1 Answers1

0

As the error says, .animation() is deprecated, with iOS 15, you need to use .animation(value:) now. where the value is the binding that you want your animation to be triggered, in your case, I assume it is selectedAnimal.

Applying this would be something like

VStack {
}
.animation(.easeIn, value: selectedAnimal) 

As discussed in comments, if you want your gridLayout to be animatable, it is a little bit more tricky. Because Arrays has to be Equatable if you want them to be animatable, since extending the GridItem is not a good solution, I came up with this:

delete your .animation method change your gridSwitch function with this:

struct GalleryView: View {
// ... irrelevant code

@State private var isGridChanged = false

func gridSwitch() {
        if (isGridChanged) {
            withAnimation {
                gridLayout = Array(repeating: .init(.flexible()), count: Int(gridColumn))
            }
        }
        else {
            gridLayout = Array(repeating: .init(.flexible()), count: Int(gridColumn))
            isGridChanged = true
        }
    }

isGridChanged is required because as you're changing your gridLayout when your View is initialized, it causes a weird bug that everything is getting scaled down when app launches because of withAnimation.

grandsirr
  • 584
  • 4
  • 19
  • I have already applied "selectedAnimal", but it doesn't change anything even though it doesn't give me an error. – Francesco5177 Oct 21 '22 at 07:27
  • when you want your animation to be triggered? – grandsirr Oct 21 '22 at 07:30
  • when I move the slider. – Francesco5177 Oct 21 '22 at 07:32
  • then use `.animation(.easeIn, value: gridColumn)` – grandsirr Oct 21 '22 at 07:34
  • I also tried this because it seemed logical, but nothing changes in this case either. :( – Francesco5177 Oct 21 '22 at 07:36
  • I get your problem, you do not want your animation to be triggered when gridColumn changes, you want your animation to be triggered when you change grid colums, right? – grandsirr Oct 21 '22 at 07:46
  • exact. the columns change as you move the slider. slider all on the left, there are 2 columns with 6 elements each. center slider, 3 columns with 4 elements each. right slider 4 columns with three elements each. – Francesco5177 Oct 21 '22 at 07:49
  • also, please read this before posting any other question on `StackOverFlow` https://xyproblem.info/ – grandsirr Oct 21 '22 at 07:56
  • perfect works thanks. :). in fact I noticed that arrays have to be equable to make them animable, but I don't know what that means :). I tried to be clear, but maybe I haven't done it enough. next time I will try to do it better. thank you. :) – Francesco5177 Oct 21 '22 at 08:29