Based on the provided code and the question you’re asking for, I will provide a more detailed explanation.
The problem seems to be related to scaling an affine transform in a view that allows for panning and zooming. The goal is to create a scaling effect where the scale factor changes depending on the direction of movement (horizontal vs vertical).
To achieve this, you’ll need to calculate the scaling factors (hScale and vScale) based on the displacement along the horizontal and vertical axes.
Here’s an example implementation:
class YourView: UIView {
var lastTouchPosition: CGPoint = .zero
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let locationInView = touch.location(in: self)
lastTouchPosition = locationInView
hScale = 1
vScale = 1
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let currentLocationInView = touch.location(in: self)
let deltaMove = CGPointDistance(currentLocationInView, lastTouchPosition)
let distance = sqrt(deltaMove.x * deltaMove.x + deltaMove.y * deltaMove.y)
// Calculate hScale and vScale
hScale -= abs(deltaMove.x) / distance * (1 - gestureRecognizer.scale)
vScale -= abs(deltaMove.y) / distance * (1 - gestureRecognizer.scale)
// Update the affine transform
self.transform = CGAffineTransformScale(self.transform, hScale, vScale)
lastTouchPosition = currentLocationInView
}
func CGPointDistance(_ point1: CGPoint, _ point2: CGPoint) -> CGPoint {
return CGPoint(x: point2.x - point1.x, y: point2.y - point1.y)
}
}
In this implementation, we’re using the touchesBegan and touchesMoved methods to track the touch movements. We calculate the displacement (deltaMove) and distance (distance) between the current location and the previous location.
We then update the hScale and vScale values based on the relative changes in the horizontal and vertical displacements, respectively. The formula used is:
hScale -= abs(deltaMove.x) / distance * (1 - gestureRecognizer.scale)
vScale -= abs(deltaMove.y) / distance * (1 - gestureRecognizer.scale)
This will adjust the scaling factors to be proportional to the displacement along each axis.
Note that we’re using a simple formula to calculate the hScale and vScale values. You can experiment with different formulas or weights to achieve the desired behavior.
Also, make sure to update the lastTouchPosition variable correctly to track the touch movement history.
Last modified on 2024-02-16