CGAffineTransform animation problem

Because apparently I haven’t used this particular animation until now, I am not sure if this is supposed to be this way, though in my opinion it shouldn’t.

Let us have a view and a subview that we want to animate. For scaling purposes, the subview is initially scaled down by 4 (scaleFactor = 0.25 ). I want an animation that scales the subview back up to its original size while translating it y points by the Y axis. Intuitively:

subview.transform = CGAffineTransform.init(scaleX: 0.25, y: 0.25)


UIView.animate(withDuration: 10.0) {

    subview.transform = CGAffineTransform.init(translationX: 0, y: y)

}


I expect the animation to progress this way:

let scaleFactor = 1.0 - 0.75 * (1 - progress)


subview.transform = CGAffineTransform.init(scaleX: scaleFactor, y: scaleFactor).concatenating(CGAffineTransform.init(translationX: 0, y: y * progress))



However, the animation performs in an unexpected way, instantly translating by some distance and then continues normally.


Playground code:


import UIKit
import PlaygroundSupport

let v = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 700, height: 700))
let v1 = UIView()

v.backgroundColor = .white
v1.backgroundColor = .blue
v1.translatesAutoresizingMaskIntoConstraints = false

v.addSubview(v1)

v1.heightAnchor.constraint(equalToConstant: 140).isActive = true
v1.widthAnchor.constraint(equalTo: v1.heightAnchor).isActive = true
v1.topAnchor.constraint(equalTo: v.topAnchor)
v1.centerXAnchor.constraint(equalTo: v.centerXAnchor).isActive = true

v1.transform = CGAffineTransform.init(scaleX: 0.3, y: 0.3)

UIView.animate(withDuration: 10.0) {
    v1.transform = CGAffineTransform.init(translationX: 0, y: 500)
}
PlaygroundPage.current.liveView = v

Replies

I would suspect a thread issue.


could you put the translation in the completion block of the scaling transform ?


May have a look here


h ttps://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html

You mean an internal issue?


I we assume this is a thread-related mistake of mine, it doesn't seem plausible to me, considering the animation has been tried out in different contexts (the one above is a simple adaptation to check it in a playground.


Moreover, an "opposite" variant (when a small subview is scaled up without being initially scaled down) works fine in the same contexts:


UIView.animate(withDuration: 10.0) {

  

      subview.transform = CGAffineTransform.init(translationX: 0, y: y).concatenating(CGAffineTransform.init(scaleX: 4.0, y: 4.0))


}

I understand the problem is the sequence of 2 affine transforms ; that's why I propose you try to put the second in the completion block of the first.


But I didn't try it myself.

I believe you misunderstood, a group of affine transforms is meant. To be precise, a translation concatenated with a scale. (Although note the scale is implicit in my very first example)

OK, effectively I read too fast.


But maybe, with the concatenation, you avoid the thread issue, because all are in the UIView.animate, which is not the case with your initial post.


For me, seems to somehow confirm the thread cause.

The below example works fine, if what you mean is this kind of flow.


v1.transform = CGAffineTransform.init(translationX: 200, y: 0)

UIView.animate(withDuration: 10.0) {

    v1.transform = CGAffineTransform.init(translationX: 0, y: 500)
}


Not a lucky exception for a thread issue, I suppose

I am late to this discussion and don't follow your coding but I do want to point out that in this code:

UIView.animate(withDuration: 10.0) { 
    v1.transform = CGAffineTransform.init(translationX: 0, y: 500) 
} 
PlaygroundPage.current.liveView = v

The last line is executed immediately after the animation begins and could interfere with the animation. Perhaps the suggestion is to place that last line into a completion handler so it is executed after the animation completes.

The line is required for the playground to visualize the view, thus placing it in a completion is senseless... The animation origins from an xcode project which obviously doesn't involve anything related to that line, so it is definitely not the cause.