0

I'm struggling trying to make an animation. This is what's happening: video

The back card was supposed to do the same animation as in the beginning of the video, but it's doing a completely different thing. I'm checking the UIView.frame at the beginning of the animation and it's the same as the first time the card enters, but obviously something is wrong... Here is the code:

func cardIn() {
    let xPosition = (self.darkCardView?.frame.origin.x)! - 300
    let yPosition = (self.darkCardView?.frame.origin.y)!

    self.initialPos = self.darkCardView.frame

    let height = self.darkCardView?.frame.size.height
    let width = self.darkCardView?.frame.size.width

    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(Double.pi/4)))!

    UIView.animate(withDuration: 1.1, animations: {
        self.darkCardView?.frame = CGRect(x: xPosition, y: yPosition, width: width!, height: height!)
        self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!
    })
}

func cardOut() {
    let xPosition = (self.darkCardView?.frame.origin.x)! - 600
    let yPosition = (self.darkCardView?.frame.origin.y)!

    let height = self.darkCardView?.frame.size.height
    let width = self.darkCardView?.frame.size.width

    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!

    UIView.animate(withDuration: 1.0, delay: 0, options: .allowAnimatedContent, animations: {
        self.darkCardView?.frame = CGRect(x: xPosition, y: yPosition, width: width!, height: height!)
        self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(-Double.pi/4)))!
    }) { (true) in
        self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!
        self.darkCardView?.frame = self.initialPos

        self.cardIn()
    }
}

Does somebody know how can I repeat the same animation that's in the beginning of the video after cardOut function is called?

Pedro de Sá
  • 760
  • 6
  • 19

3 Answers3

0

Given that we do not know where/when you are calling the above two functions I can only take a guess at what is happening.

So you have an animate in and an animate out, but what about a reset function?

Timeline: Animate the card in. ... Eventually animate the card out ... Reset the cards location to off screen to the right (location before animating in for the first time) ... animate the card in ... Repeat, ect....

Jerland2
  • 1,096
  • 11
  • 28
  • I "reseted" the card to its initial position in the *cardOut*'s completion block. I used this two lines of code: `self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))! self.darkCardView?.frame = self.initialPos` I set the angle back to 0 again and this *initialPos* is a variable that I create in *viewDidLoad* that takes the frame of the back card – Pedro de Sá Sep 28 '17 at 18:10
0

Note that if you set a view's transform to anything other than the identity transform then the view's frame rect becomes "undefined". You can neither set it to a new value nor read it's value reliably.

You should change your code to use the view's center property if you're changing the transform.

As Jerland points out in their post, you also probably need to reset your back card to it's starting position before beginning the next animation cycle. (Set it to hidden, put it's center back to the starting position and set it's transform back to the identity transform.

EDIT:

This code:

UIView.animate(withDuration: 1.0, delay: 0, options: .allowAnimatedContent, animations: {
    self.darkCardView?.frame = CGRect(x: xPosition, y: yPosition, width: width!, height: height!)
    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(-Double.pi/4)))!
}) { (true) in
    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!
    self.darkCardView?.frame = self.initialPos

    self.cardIn()
}

Does not set the transform to identity. Try changing that line to

    self.darkCardView?.transform = .identity
Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I tried checking the card's center, as you said. But the center in the end of *cardOut* is the same as in the beginning of *cardIn*. I also reseted the card, as you and and Jerland said, but I've done it in the cardOut's completion, that's why the code does not have a reset function. – Pedro de Sá Sep 28 '17 at 18:39
  • Did it and you were right. Indeed, it wasn't set to it's identity transform. Although, it didn't solve the animation's problem... I added a new answer where I said that only changing the call to `self.cardIn()` function to `self.viewDidLoad()` is enough for the animation run as expected, but I still have no clue why that solves my problem... – Pedro de Sá Sep 28 '17 at 20:56
0

I managed to solve the animation problem by calling viewDidLoad() instead of calling self.cardIn() in the end o cardOut completion block. But I don't want to depend on calling viewDidLoad every time a new card has to enter the screen...

Also, I didn't set any properties of the back card in viewDidLoad. I only have it in the .xib file. Any ideas?

Pedro de Sá
  • 760
  • 6
  • 19