IOS画像ルーニー/ブラウザジェスチャースケーリング

4809 ワード

プロジェクトの需要:画像ブラウザ(左右に切り替わります。ジェスチャーのズーム機能をサポートする必要があります。)https://github.com/Shannoon/XLPhotoBrowser.git ネットで多くのフレームを探しましたが、合わないです。魏希の共有に感謝します。http://www.jianshu.com/p/03c81ee888f4 。今貼り出したら予備です。
効果図は以下の通りです
photo Browser.gif
Github:https://github.com/briceZhao/ZoomingImageBrowser
コード
  • AZCollection View.m中
  • - (void)configSubViews{
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        scrollView.delegate = self;
        scrollView.maximumZoomScale = 3.0;//      
        scrollView.minimumZoomScale = 1.0;//      
        scrollView.showsVerticalScrollIndicator = NO;
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.backgroundColor = [UIColor blackColor];
        [self addSubview:scrollView];
        self.scrollView = scrollView;
        
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.userInteractionEnabled = YES;// UIImageView      ,      
        UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
        [doubleTap setNumberOfTapsRequired:2];
        [imageView addGestureRecognizer:doubleTap];//      
        [scrollView addSubview:imageView];
        self.imageView = imageView;
    }
    
  • 属性のsetImage方法において、UImageViewの画像とサイズとScrrollViewのスケーリング比率
  • を再設定する。
    - (void)setImage:(UIImage *)image{
        _image = image;
        self.imageView.image = image;
        CGFloat width = image.size.width;
        CGFloat height = image.size.height;
        CGFloat maxHeight = self.scrollView.bounds.size.height;
        CGFloat maxWidth = self.scrollView.bounds.size.width;
        //        view  ,     
        if(width > maxWidth || height > width){
            CGFloat ratio = height / width;
            CGFloat maxRatio = maxHeight / maxWidth;
            if(ratio < maxRatio){
                width = maxWidth;
                height = width*ratio;
            }else{
                height = maxHeight;
                width = height / ratio;
            }
        }
        self.scrollView.contentSize = CGSizeMake(width, height);
        [self.scrollView setZoomScale:1.f];
        self.imageView.frame = CGRectMake((maxWidth - width) / 2, (maxHeight - height) / 2, width, height);
        [self.scrollView layoutIfNeeded];
    }
    
  • UScrrollView Delegateを実現し、真の画像スケーリング処理
  • #pragma mark UIScrollViewDelegate
    //    UIScrolleView ,  UIImageView   
    -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
        return self.imageView;
    }
    
    //             
    -(void)scrollViewDidZoom:(UIScrollView *)scrollView{
        CGSize originalSize = _scrollView.bounds.size;
        CGSize contentSize = _scrollView.contentSize;
        CGFloat offsetX = originalSize.width > contentSize.width ? (originalSize.width - contentSize.width) / 2 : 0;
        CGFloat offsetY = originalSize.height > contentSize.height ? (originalSize.height - contentSize.height) / 2 : 0;
        self.imageView.center = CGPointMake(contentSize.width / 2 + offsetX, contentSize.height / 2 + offsetY);
    }
    
    - (void)handleDoubleTap:(UITapGestureRecognizer *)recongnizer
    {
        UIGestureRecognizerState state = recongnizer.state;
        switch (state) {
            case UIGestureRecognizerStateBegan:
                break;
            case UIGestureRecognizerStateChanged:
                break;
            case UIGestureRecognizerStateCancelled:
            case UIGestureRecognizerStateEnded:
            {
                //       ,    
                CGPoint touchPoint = [recongnizer locationInView:recongnizer.view];
                BOOL zoomOut = self.scrollView.zoomScale == self.scrollView.minimumZoomScale;
                CGFloat scale = zoomOut?self.scrollView.maximumZoomScale:self.scrollView.minimumZoomScale;
                [UIView animateWithDuration:0.3 animations:^{
                    self.scrollView.zoomScale = scale;
                    if(zoomOut){
                        CGFloat x = touchPoint.x*scale - self.scrollView.bounds.size.width / 2;
                        CGFloat maxX = self.scrollView.contentSize.width-self.scrollView.bounds.size.width;
                        CGFloat minX = 0;
                        x = x > maxX ? maxX : x;
                        x = x < minX ? minX : x;
                        
                        CGFloat y = touchPoint.y * scale-self.scrollView.bounds.size.height / 2;
                        CGFloat maxY = self.scrollView.contentSize.height-self.scrollView.bounds.size.height;
                        CGFloat minY = 0;
                        y = y > maxY ? maxY : y;
                        y = y < minY ? minY : y;
                        self.scrollView.contentOffset = CGPointMake(x, y);
                    }
                }];
                
            }
                break;
            default:break;
        }
    }
    
    以上のコードは写真のロードショーやブラウザ/写真ビューアなどのブラウズ画像類、ジェスチャーズームの効果を実現できます。以上のコードは魏希の共有を参考にしました。http://www.jianshu.com/p/03c81ee888f4 原作者に感謝します。もっと多くの人にこの方法を使ってほしいです。