swiftanimation

Swift: How would I get my UIImageView / image to stay horizontally flipped while translating it across the X Axis?


I'm trying to move an animated image across the x-axis back and forth however when it moves right I'd like for it to flip horizontally (so the image faces that way) and when it comes back left to flip back to its original position. My code has made it horizontally flipped yet while moving across the x axis it animates back to its original.

First I tried CGAffineTransform(scaleX: -1, y: 1) and it worked to flip horizontally yet kept spinning back during the UIView.animate (the commented out code)

func dragonMovementLeft() { 
    //let mirrorTransform = CGAffineTransform(scaleX: -1, y: 1) 
    //self.dragonImage.transform = mirrorTransform 
    let dragon_anim_flipped = flipImages(images: dragon_anim) 
    dragonImage.animationImages = dragon_anim_flipped 
    dragonImage.startAnimating() 
    UIView.animate(withDuration: 5.0, animations: { 
    self.dragonImage.transform = CGAffineTransform(translationX: 100, y: 0) 
    //look up why you need .self for it to work }) 
{ _ in 
//self.dragonImage.transform = CGAffineTransform.identity 
//self.dragonMovementRight() } }

Next I tried creating this function to flip the UIImages themselves but I couldn't get it to work


func flipImages(images: [UIImage] ) -> [UIImage] {
    var flippedImages: [UIImage] = []
    for image in images {
        flippedImages.append(image.withHorizontallyFlippedOrientation())
    }
    return flippedImages
}

Solution

  • By doing things like:

    self.dragonImage.transform = CGAffineTransform(translationX: 100, y: 0) 
    

    You have undone all the transformations you have previously done on it. What you want is to append an additional transformation to the current transform.

    You can do:

    dragonImage.transform = CGAffineTransform(scaleX: -1, y: 1)
    UIView.animate(withDuration: 5) {
        self.dragonImage.transform = self.dragonImage.transform.translatedBy(x: -100, y: 0)
    } completion: { _ in
        self.dragonImage.transform = self.dragonImage.transform.scaledBy(x: -1, y: 1)
        UIView.animate(withDuration: 5) {
            self.dragonImage.transform = self.dragonImage.transform.translatedBy(x: -100, y: 0)
        }
    }
    

    We are basically doing:

    1. flip
    2. move by -100
    3. flip
    4. move by -100

    Note that we use a -100 offset for both going left and going right. This is because when we go right, the view has already been flipped, so a negative offset actually moves it to the right.