Set a UIView scale transform without effecting other transforms

Darren picture Darren · Jul 31, 2014 · Viewed 7.5k times · Source

I have a UIView that I scale down when it is touched and scale back up when the touch is ended or cancelled.

I had been scaling the view like this

Scale down:

CGAffineTransform transform = CGAffineTransformMakeScale(0.95, 0.95);
self.transform = transform;

Scale up:

CGAffineTransform transform = CGAffineTransformMakeScale(1.0, 1.0);
self.transform = transform;

This doesn't preserve any other transform. I know I can use this to preserve the old transforms:

Scale down:

CGAffineTransform transform = CGAffineTransformScale(self.transform, 0.95, 0.95);
self.transform = transform;

Scale up:

CGAffineTransform transform = CGAffineTransformScale(self.transform, 1.0, 1.0);
self.transform = transform;

But of course here the scale up has no effect- plus there is potential to have cumulative scale down animations applied. Basically I want a way to apply the scale transform absolutely without affecting any other transform. Is there a way to do this? I don't think using 1.0/0.95 for the scale up factor, because it is possible the view could receive two touches before one is cancelled or ended.

I think I am asking the same thing as this question: Applying just the scale component of a CGAffineTransform to a UIView but I don't think the answers here will work for me.

I am targeting iOS 7 and above.

Answer

DCForever picture DCForever · Jul 31, 2014

I am not sure if this is exactly what you are looking for but for me I need the scale to be absolutely consistent all the time so I modify the matrix directly.

CATransform3D transform = layer.transform;
if (makeSmaller)
{
    // Scale to 0.9
    transform.m11 = 0.9f;
    transform.m22 = 0.9f;
}
// Cell needs to grow to normal size
else if (restoreToOriginal)
{
    // Scale to 1.0 again
    transform.m11 = 1.0f;
    transform.m22 = 1.0f;
}

// Set the desired Y translation
transform.m42 = desiredffset;
layer.transform = transform;