Search code examples
iosswiftanimationuiimageview

Swift - scale background while retaining top anchor


How can I scale a UIImageView while retaining the top anchor?

I tried:

UIView.animate(withDuration: 0.3, animations: {
        self.backGroundImage.contentMode = .scaleToFill
        self.backGroundImage.transform = CGAffineTransform(scaleX: 3, y: 3)
        self.backGroundImage.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    })

That scales the image but the anchor point is the middle of the image. It seems like setting the topAnchor doesn't do anything. Is there a way to set some sort of "scaleAnchor" or some other solution? In the end I would like to achieve this:

enter image description here

Update

This is how I constrain the view:

NSLayoutConstraint.activate([

        // constrain background image
        backGroundImage.topAnchor.constraint(equalTo: view.topAnchor),
        backGroundImage.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        backGroundImage.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        backGroundImage.trailingAnchor.constraint(equalTo: view.trailingAnchor), )]

Solution

  • This works for me in Swift 5.1:

    public extension UIView {
    
        func applyTransform(withScale scale: CGFloat, anchorPoint: CGPoint) {
            let xPadding = (scale - 1) * (anchorPoint.x - 0.5) * bounds.width
            let yPadding = (scale - 1) * (anchorPoint.y - 0.5) * bounds.height
            transform = CGAffineTransform(scaleX: scale, y: scale).translatedBy(x: xPadding, y: yPadding)
        }
    }
    

    Example:

    yourView.applyTransform(withScale: 3, anchorPoint: CGPoint(x: 0.5, y: 0))