iOS多層画像(view)ドラッグ、ズームジェスチャー(拡大縮小倍数制限)処理

5290 ワード

マルチレイヤピクチャ(必要に応じてピクチャを1枚にまとめることができない)についてジェスチャー処理を行う場合、単純にドラッグ、スケール、回転ジェスチャー を行うと問題はありません.しかし、imageViewに1つ以上のピクチャを追加すると、制限を追加すると、サブビューのピクチャがジェスチャーに従わないことになります.
まず、ネット上で提供される解決策は、画像を記録する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];
    }
}

最后に书きます:もちろんプロジェクトの中で何度も使うならば、UIViewcategoryを添加することができて、あるいは自分でカプセル化して、一つ一つ述べません.
PS:大いに役に立つと思ったら惜しみなく好きになってください.