Say, I have two CGRects, CGRect A and CGRect B. My UIView's frame is the same as CGRect B, but I want to create an animation showing the UIView transitioning from frame A to B.
I'm trying to do this by changing the transform property of the UIView, so I don't have to mess around with its frame too much. However, I need the CGAffineTransform to make this possible. What is the best way to calculate this transform?
The previous answers didn't work for me. This should work:
extension CGAffineTransform {
init(from source: CGRect, to destination: CGRect) {
let t = CGAffineTransform.identity
.translatedBy(x: destination.midX - source.midX, y: destination.midY - source.midY)
.scaledBy(x: destination.width / source.width, y: destination.height / source.height)
self.init(a: t.a, b: t.b, c: t.c, d: t.d, tx: t.tx, ty: t.ty)
}
}
func transformFromRect(from source: CGRect, toRect destination: CGRect) -> CGAffineTransform {
return CGAffineTransform.identity
.translatedBy(x: destination.midX - source.midX, y: destination.midY - source.midY)
.scaledBy(x: destination.width / source.width, y: destination.height / source.height)
}
func transformFromRect(from: CGRect, toRect to: CGRect) -> CGAffineTransform {
let transform = CGAffineTransformMakeTranslation(CGRectGetMidX(to)-CGRectGetMidX(from), CGRectGetMidY(to)-CGRectGetMidY(from))
return CGAffineTransformScale(transform, to.width/from.width, to.height/from.height)
}
+ (CGAffineTransform) transformFromRect:(CGRect)sourceRect toRect:(CGRect)finalRect {
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, -(CGRectGetMidX(sourceRect)-CGRectGetMidX(finalRect)), -(CGRectGetMidY(sourceRect)-CGRectGetMidY(finalRect)));
transform = CGAffineTransformScale(transform, finalRect.size.width/sourceRect.size.width, finalRect.size.height/sourceRect.size.height);
return transform;
}
I haven't been able to find a convenience method of any kind for this, so I resorted to tried and true matrix calculations to achieve this.
Given a CGRect A and CGRect B, to calculate the transformation needed to go from A to B, do the following:
CGAffineTransform transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -A.origin.x, -A.origin.y);
transform = CGAffineTransformScale(transform, 1/A.size.width, 1/A.size.height);
transform = CGAffineTransformScale(transform, B.size.width, B.size.height);
transform = CGAffineTransformTranslate(transform, B.origin.x, B.origin.y);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With