0

I am implementing a pinch-based zoom and the scaling occurs from the top left corner of the view as opposed to scaling from the center. After a few attempts (this seems like a cs origin problem or the like), not finding a good solution for this but there must be some (perhaps obvious) way to scale from the view's center. If this has been answered before, would appreciate a pointer to the answer (not found after extensive search). If not, will appreciate inputs on correct approach.

Edit following answers (thanks): Here is the code I was initially using:

func pinchDetected(pinchGestureRecognizer: UIPinchGestureRecognizer) {

    let scale = pinchGestureRecognizer.scale
    view.transform = CGAffineTransformScale(view.transform, scale, scale)
    pinchGestureRecognizer.scale = 1.0

}

Upon pinch, the content inside the view would be expanding rightward and downward as opposed to same + leftward and upward (hence the assumption it is not scaling "from the center"). Hope this makes it clearer.

aac
  • 21
  • 4

3 Answers3

1

It's hard to know whats going on without seeing your code. By default transforms do act on a views centre, which seems to be what you want. You can make the transforms act on some other point by changing the anchorPoint property on the views layer.

Or you can create a transform about an arbitrary point by translating the origin to that point, doing your transform, and translating back again. e.g:

func *(left: CGAffineTransform, right: CGAffineTransform) -> CGAffineTransform {
    return left.concatenating(right)
}


public extension CGAffineTransform {
    static func scale(_ scale:CGFloat, aboutPoint point:CGPoint) -> CGAffineTransform {
        let Tminus = CGAffineTransform(translationX: -point.x, y: -point.y)
        let S = CGAffineTransform(scaleX: scale, y: scale)
        let Tplus = CGAffineTransform(translationX: point.x, y: point.y)
    
        return Tminus * S * Tplus
    }
}

view.transform = CGAffineTransform.scale(2.0, aboutPoint:point)

where the point is relative to the origin, which by default is the center.

Hugo Alonso
  • 6,684
  • 2
  • 34
  • 65
DavidEC
  • 148
  • 6
  • I checked your code and for me its scales a view about its center point as expected. So I think the problem is elsewhere. Have you checked that the view.layer.anchorPoint is in the center? It should be (0.5,0.5). Another possibility is that you are not scaling the view that you think you are scaling. Perhaps the top corner of your view is the center of a superview that you are really scaling? – DavidEC Feb 21 '17 at 10:25
  • the anchor point is set correctly - it is the case that the view is added to a superview which receives the pinch events. However, the function handling those events only scales the child view and that child view should scale independently no? – aac Feb 21 '17 at 15:41
  • sure, the transform should effect whatever view its set on independently. – DavidEC Feb 21 '17 at 15:51
0

This is the code you are looking for

view.transform = CGAffineTransformScale(view.transform, 1.1, 1.1);

or in Swift

view.transform = view.transform.scaledBy(x: 1.1, y: 1.1)

This will increase views height and width by the provided scale. Now you can control the amount by using a gesture recognizer.

Naresh
  • 334
  • 1
  • 4
  • 17
  • Thanks - I have edited my question to include a code excerpt and this was what I was already using if I am not mistaken. The result however would be that the content would seem to show the content expanding from the top left corner of the view rightward and downward. Hope this clarifies and thanks again. – aac Feb 21 '17 at 02:55
0

You should be able to just use the code in this question to get it to zoom from the center. If you want it to zoom from the fingers, see the answer to that question.

Community
  • 1
  • 1
Daniel Legler
  • 527
  • 1
  • 6
  • 16
  • Thanks for the pointer - will add a comment if any question on it but hopefully this will provide the answer. – aac Feb 21 '17 at 02:51