在手势处理时,要注意,为了能跟随用户捏合手势的中心进行缩放,我们要在手势过程中移动缩放中心到手指中心,这里我们判断了 pinGesture 的 state 来确定手势开始、进行中和结束阶段。
if (pinGesture.state == UIGestureRecognizerStateBegan || pinGesture.state == UIGestureRecognizerStateChanged) {
// 移动缩放中心到手指中心
CGPoint pinchCenter = [pinGesture locationInView:view.superview];
CGFloat distanceX = view.frame.origin.x - pinchCenter.x;
CGFloat distanceY = view.frame.origin.y - pinchCenter.y;
CGFloat scaledDistanceX = distanceX * pinGesture.scale;
CGFloat scaledDistanceY = distanceY * pinGesture.scale;
CGRect newFrame = CGRectMake(view.frame.origin.x + scaledDistanceX - distanceX, view.frame.origin.y + scaledDistanceY - distanceY, view.frame.size.width * pinGesture.scale, view.frame.size.height * pinGesture.scale);
view.frame = newFrame;
pinGesture.scale = 1;
}
pinchCenter 就是捏合手势的中心,我们获取到当前图片 view 的 frame,然后计算当前 view 与手势中心的 x、y 坐标差,再根据手势缩放值 scale,创建出新的 frame
CGRect newFrame = CGRectMake(view.frame.origin.x + scaledDistanceX - distanceX, view.frame.origin.y + scaledDistanceY - distanceY, view.frame.size.width * pinGesture.scale, view.frame.size.height * pinGesture.scale);
这个 frame 的中心坐标就在缩放手势的中心,将新的 frame 赋值给图片 view,从而实现依据手势中心进行缩放的效果。
而在手势结束阶段,我们要对图片缩放进行边界保护,既不能放大过大,也不能缩小过小。
CGFloat ration = view.frame.size.width / self.originalFrame.size.width;
// 缩放过大
if (ration > 5) {
CGRect newFrame = CGRectMake(0, 0, self.originalFrame.size.width * scaleRation, self.originalFrame.size.height * scaleRation);
view.frame = newFrame;
}
// 缩放过小
if (ration < 0.25) {
view.frame = self.originalFrame;
}
同时缩放后如果图片与裁剪区域出现了空白区域,还要对图片的位置进行修正以保证图片始终是覆盖全裁剪区域的。
// 对图片进行位置修正
CGRect resetPosition = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
if (resetPosition.origin.x >= self.cropAreaX) {
resetPosition.origin.x = self.cropAreaX;
}
if (resetPosition.origin.y >= self.cropAreaY) {
resetPosition.origin.y = self.cropAreaY;
}
if (resetPosition.size.width + resetPosition.origin.x < self.cropAreaX + self.cropAreaWidth) {
CGFloat movedLeftX = fabs(resetPosition.size.width + resetPosition.origin.x - (self.cropAreaX + self.cropAreaWidth));
resetPosition.origin.x += movedLeftX;
}
if (resetPosition.size.height + resetPosition.origin.y < self.cropAreaY + self.cropAreaHeight) {
CGFloat moveUpY = fabs(resetPosition.size.height + resetPosition.origin.y - (self.cropAreaY + self.cropAreaHeight));
resetPosition.origin.y += moveUpY;
}
view.frame = resetPosition;










