iOS多层图片(view)拖拉、缩放手势(限制放大缩小倍数)处理

2017-01-26  本文已影响0人  水爱上鱼

当我们对多层图片(由于需求决定不能将图片合并成一张)进行手势处理的时候,单纯的进行拖拉、缩放、旋转手势不限制倍率时不会出什么问题的。但是当我们添加的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:如果各位大大觉得有用还请不吝惜的点下喜欢~

上一篇下一篇

猜你喜欢

热点阅读