Skip to content

Instantly share code, notes, and snippets.

@christianselig
Created May 9, 2023 17:45
Show Gist options
  • Save christianselig/a40dcf539de1da8dbd5872019faa5e6e to your computer and use it in GitHub Desktop.
Save christianselig/a40dcf539de1da8dbd5872019faa5e6e to your computer and use it in GitHub Desktop.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let separatorLine = UIView(frame: CGRect(x: 50.0, y: 0.0, width: 1.0, height: view.bounds.height))
separatorLine.backgroundColor = .systemRed
view.addSubview(separatorLine)
// Cat photo can be found here: https://unsplash.com/photos/MEb2jandkbc
let image = UIImage(named: "pinecat")!
let imageView = UIImageView(image: image)
let width = 200.0
imageView.frame = CGRect(x: 50.0, y: 100.0, width: width, height: width * image.size.height / image.size.width)
view.addSubview(imageView)
imageView.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)
let translateTransform = CGAffineTransform(translationX: -imageView.bounds.width / 2.0, y: 0.0)
imageView.transform = translateTransform
// Stretch image out
UIView.animate(withDuration: 1.0, delay: 1.0) {
let scaleTransform = CGAffineTransform(scaleX: 2.0, y: 1.0)
imageView.transform = scaleTransform.concatenating(translateTransform)
} completion: { didComplete in
// Reset back to original state
UIView.animate(withDuration: 1.0, delay: 1.0) {
imageView.transform = .identity
imageView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
}
}
}
}
@simonbs
Copy link

simonbs commented May 9, 2023

Example of the animation can be seen here.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let separatorLine = UIView(frame: CGRect(x: 50.0, y: 0.0, width: 1.0, height: view.bounds.height))
        separatorLine.backgroundColor = .systemRed
        view.addSubview(separatorLine)

        // Cat photo can be found here: https://unsplash.com/photos/MEb2jandkbc
        let image = UIImage(named: "pinecat")!
        let imageView = UIImageView(image: image)
        let width = 200.0
        imageView.frame = CGRect(x: 50.0, y: 100.0, width: width, height: width * image.size.height / image.size.width)
        view.addSubview(imageView)

        UIView.animate(withDuration: 1.0, delay: 1.0) {
            let scale = CGPoint(x: 2, y: 1)
            let newWidth = imageView.bounds.width * scale.x
            let scaleTransform = CGAffineTransform(scaleX: scale.x, y: scale.y)
            let translateTransform = CGAffineTransform(translationX: (newWidth - imageView.bounds.width) / 2, y: 0)
            imageView.transform = scaleTransform.concatenating(translateTransform)
        } completion: { didComplete in
            // Reset back to original state
            UIView.animate(withDuration: 1.0, delay: 1.0) {
                imageView.transform = .identity
            }
        }
    }
}

@CraigSiemens
Copy link

☝️ That's probably a better option doing it all with the transform and not messing with the anchor. But incase changing the anchor is needed for other reasons, here's how it can be done.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let separatorLine = UIView(frame: CGRect(x: 50.0, y: 0.0, width: 1.0, height: view.bounds.height))
        separatorLine.backgroundColor = .systemRed
        view.addSubview(separatorLine)
        
        // Cat photo can be found here: https://unsplash.com/photos/MEb2jandkbc
        let image = UIImage(named: "pinecat")!
        let imageView = UIImageView(image: image)
        let width = 200.0
        imageView.frame = CGRect(x: 50.0, y: 100.0, width: width, height: width * image.size.height / image.size.width)
        view.addSubview(imageView)

        imageView.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)
        
        let translateTransform = CGAffineTransform(translationX: -imageView.bounds.width / 2.0, y: 0.0)
        imageView.transform = translateTransform
        
        // Stretch image out
        UIView.animate(withDuration: 1.0, delay: 1.0) {
            let scaleTransform = CGAffineTransform(scaleX: 2.0, y: 1.0)
            imageView.transform = scaleTransform.concatenating(translateTransform)
        } completion: { didComplete in
            // Reset back to original state
            UIView.animate(withDuration: 1.0, delay: 1.0) {
                imageView.transform = translateTransform
            } completion: { _ in
                imageView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
                imageView.transform = .identity
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment