Place anchor point at the centre of the screen while doing gestures
Since the question is mostly answered in the edits, I don't want to repeat myself too much.
Broadly what I changed from the code posted in the original question:
- Deleted calls to
adjustAnchorPoint
function in pinch and rotation gesture functions. Placed this piece of code in pan gesture function, so that the anchor point would update its position after panning the photo:
if gestureRecognizer.state == .ended { self.centerAnchorPoint() }
Updated
centerAnchorPoint
function to work for rotation.
A fully working centerAnchorPoint
function (rotation included):
func centerAnchorPoint() { // Scale factor photo.transform = photo.transform.rotated(by: -angle) let curScale = photo.frame.size.width / photo.layer.bounds.size.width photo.transform = photo.transform.rotated(by: angle) // Position of the current anchor point let currentPosition = photo.layer.anchorPoint self.setAnchorPoint(CGPoint(x: 0.5, y: 0.5), forView: photo) // Center of the image let imageCenter = CGPoint(x: photo.center.x, y: photo.center.y) self.setAnchorPoint(currentPosition, forView: photo) // Center of the screen let screenCenter = CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY) // Distance between the centers let distanceX = screenCenter.x - imageCenter.x let distanceY = screenCenter.y - imageCenter.y // Apply rotational matrix to the distances let distX = distanceX*cos(angle)+distanceY*sin(angle) let distY = -distanceX*sin(angle)+distanceY*cos(angle) let incrementX = (distX)/(curScale*UIScreen.main.bounds.size.width) let incrementY = (distY)/(curScale*UIScreen.main.bounds.size.height) // Find new anchor point let newAnchorPoint = CGPoint(x: 0.5+incrementX, y: 0.5+incrementY) self.setAnchorPoint(newAnchorPoint, forView: photo)}
The key things to notice here is that the rotation matrix has to be applied to distanceX and distanceY. The scale factor is also updated to remain the same throughout the rotation.