当我们对多层图片(由于需求决定不能将图片合并成一张)进行手势处理的时候,单纯的进行拖拉、缩放、旋转手势不限制倍率
时不会出什么问题的。但是当我们添加的imageView
上不止一个图片的时候,添加限制就会导致其子视图的图片不跟随手势
首先网上给出的解决办法是记录图片的frame
:
~~//错误示范(多层图片)
//记录其oldFrame & imageView.frame
{
CGRect oldFrame;
CGRect largeFrame;
UIImageView *img //操作的视图
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
img.userInteractionEnabled = YES;
[self addGestureRecognizerToView:img];
oldFrame = img.frame;
largeFrame = CGRectMake(0 - ScreenWidth, 0 - ScreenHeight, 3 * oldFrame.size.width, 3 * oldFrame.size.height); //3倍放大限制
}
- (void) pinchView:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
UIView *view = pinchGestureRecognizer.view;
if (pinchGestureRecognizer.state == UIGestureRecognizerStateBegan || pinchGestureRecognizer.state == UIGestureRecognizerStateChanged) {
view.transform = CGAffineTransformScale(view.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);
if (_backImage.frame.size.width <= oldFrame.size.width ) {
view.frame = oldFrame;
}
if (_backImage.frame.size.width > 3 * oldFrame.size.width) {
view.frame = largeFrame;
}
pinchGestureRecognizer.scale = 1;
}
}
~~
这个方法只会对其图片本身进行限制,不会限制它的子视图,所以只能放弃。
此时只能从另一方面入手考虑,既然手势改变的是view.transform
,我们就手动改transform
。
command
点进去发现是一个结构体
typedef struct CGAffineTransform CGAffineTransform;
#include
#include
CF_IMPLICIT_BRIDGING_ENABLED
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
经过分析发现,我们操作view
的时候其是根据transform
判断view
的手势的。所以我们可以根据transform
来重置view
的倍率或限制超出屏幕的大小
//记录其imag
{
UIImageView *img //操作的视图
CGRect oldFrame;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//after alloc your imageView or view
oldFrame = img.frame;
img.userInteractionEnabled = YES;
[self addGestureRecognizerToView:img];
}
#pragma mark - 处理所有手势
// 正确姿势
- (void) addGestureRecognizerToView:(UIView *)view
{
// 根据需求选择要添加的手势
// 旋转手势
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateView:)];
[view addGestureRecognizer:rotationGesture];
// 缩放手势
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];
[view addGestureRecognizer:pinchGesture];
// 移动手势
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];
[view addGestureRecognizer:panGesture];
}
#pragma mark 处理旋转
- (void) rotateView:(UIRotationGestureRecognizer *)rotationGesture
{
UIView *view = rotationGesture.view;
if (rotationGesture.state == UIGestureRecognizerStateBegan || rotationGesture.state == UIGestureRecognizerStateChanged) {
view.transform = CGAffineTransformRotate(view.transform, rotationGesture.rotation);
[rotationGesture setRotation:0];
//log下查看view.transform是怎么处理原理
}
}
- (void) pinchView:(UIPinchGestureRecognizer *)pinchGesture
{
UIView *view = pinchGesture.view;
if (pinchGesture.state == UIGestureRecognizerStateBegan || pinchGesture.state == UIGestureRecognizerStateChanged) {
view.transform = CGAffineTransformScale(view.transform, pinchGesture.scale, pinchGesture.scale);
if (_backImage.frame.size.width <= oldFrame.size.width ) {
[UIView beginAnimations:nil context:nil]; // 开始动画
[UIView setAnimationDuration:0.5f]; // 动画时长
/**
* 固定一倍
*/
view.transform = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
[UIView commitAnimations]; // 提交动画
}
if (_backImage.frame.size.width > 3 * oldFrame.size.width) {
[UIView beginAnimations:nil context:nil]; // 开始动画
[UIView setAnimationDuration:0.5f]; // 动画时长
/**
* 固定三倍
*/
view.transform = CGAffineTransformMake(3, 0, 0, 3, 0, 0);
[UIView commitAnimations]; // 提交动画
}
DLog(@"%@",NSStringFromCGAffineTransform(view.transform)) ;
pinchGesture.scale = 1;
}
}
#pragma mark 处理拖拉
-(void)panView:(UIPanGestureRecognizer *)panGesture
{
UIView *view = panGesture.view;
if (panGesture.state == UIGestureRecognizerStateBegan || panGesture.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [panGesture translationInView:view.superview];
[view setCenter:(CGPoint){view.center.x + translation.x, view.center.y + translation.y}];
[panGesture setTranslation:CGPointZero inView:view.superview];
}
}
写在最后:当然如果项目中多次使用的话,可以给UIView
添加category
,或者自行进行封装,就不一一赘述了。
PS:如果各位大大觉得有用还请不吝惜的点下喜欢~