Home > OS >  How to create array of different types that all conforms Equatable protocol?
How to create array of different types that all conforms Equatable protocol?

Time:11-17

I'm following a SwiftUI course, and I want to animate my view with multiple values. In the tutorial, the animation modifier is used without the value parameter but XCode says it's deprecated. animation modifier requires a value now.

My goal is to add multiple values to that animation, I think of Array for it. I have two boolean values, show and showCard and one CGSize.

I cast this array with as [Any] because Array of two boolean and 1 CGSize gives this error:

Cannot convert value of type 'CGSize' to expected element type 'Bool'

When I use as [Any], I can't conform Equatable.

Protocol 'Any' as a type cannot conform to 'Equatable'

And then I've tried like this:

as [Any : Equatable]

and error is:

Type 'Any' does not conform to protocol 'Hashable'

I can try lot of things but I want to understand:

  1. How to give multiple values for 1 animation?

or

  1. How to make an Array with different types, which all conforms to a protocol?

Code of my view:

    BackCardView()
        .frame(width: 340, height: 220)
        .background(Color(show ? "card4" : "card3"))
        .cornerRadius(20.0)
        .shadow(radius: 20)
        .offset(x: 0, y: show ? -200 : -20)
        .offset(x: viewState.width, y: viewState.height)
        .offset(y: showCard ? -140 : 0)
        .scaleEffect(showCard ? 1 : 0.95)
        .rotationEffect(Angle(degrees: (show ? 0: 5)))
        .rotationEffect(Angle(degrees:  showCard ? -5 : 0))
        .rotation3DEffect(Angle(degrees: showCard ? 5 : 0), axis: (x: 10.0, y: 0, z: 0))
        .blendMode(.hardLight)
        .animation(.easeInOut(duration: 0.3), value: [show, showCard, viewState])

CodePudding user response:

You need to apply various animations separately, e.g.

.animation(.easeInOut(duration: 0.3), value: show)
.animation(.easeInOut(duration: 0.3), value: showCard)
.animation(.easeInOut(duration: 0.3), value: viewState)

That is: each modifier applies the same animation to the view, but on different conditions.

CodePudding user response:

the problem here is that you the array that you need to transmit should be conform to equatable :

https://developer.apple.com/documentation/swift/equatable

When your array contains Bool and CGSize , swift can't perform equality between a Bool and CGSize. And In this context it doesn't make sens to make them equatable.

To realise what you want to do you can simply add 2 animation :

.animation(.default, value: [show, showCard])
.animation(.default, value: viewState)

CodePudding user response:

Try defining your array as type [Equatable].

That means "An array of things, all of which conform to the Equatable protocol".

  • Related