iOS圖片瀏覽器控件 放大,縮小,UIScrollView


GitHub地址 https://github.com/JerryWanXuJie/XJAlbum

圖片瀏覽器主要通過 UIScrollView 實現  在一個大的ScollView里面套 n個ScollView

UIScrollView里主要是有兩個屬性,contentSize和contentoffset , contentSize 是設定UIScrollView的可交互的大小,contentoffset偏移量

設置第一層 UIScollView 主要是設置 contentSize 和 contentoffset , contentSize 是根據圖片的個數來設定,contentoffset根據當前圖片編號設定
wholeScoll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, myScreenWidth, myScreenHeight)]; wholeScoll.contentOffset = CGPointMake(wholeScoll.frame.size.width*mcurpage, 0);
   wholeScoll.contentSize = CGSizeMake(myScreenWidth*mImgLocationArr.count, myScreenHeight);

        // 主要代碼是通過for 循環添加第二層UIScrollView

      for (int i = 0; i<mImgLocationArr.count; i++) {

 

        //設置 imageview

          UIImageView * imgview = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, myScreenWidth, myScreenHeight)];

          imgview.contentMode = UIViewContentModeScaleAspectFit;

        //設置 scrollview

          UIScrollView * singleview = [[UIScrollView alloc]initWithFrame:CGRectMake(myScreenWidth*i,0,myScreenWidth, myScreenHeight)];

          [wholeScoll addSubview:singleview];

          [singleview addSubview:imgview];

        // 添加手勢

          [self addGestureRecognizer];

    }

 

圖片瀏覽器中圖片可以左右滑動,可以雙擊放大,可以手勢捏合放大縮小

圖片瀏覽器中主要有三種手勢分別是單擊 singleTap 雙擊doubleTap 捏合 pinchGesture 和UIScrollView自帶的滑動手勢

singleTap 手勢主要是返回上一頁面,如果觸發singleTap的時候圖片已經放大,那么先將圖片初始化大小和坐標

因為singleTap 和 doubleTap 是屬於同一手勢類,會產生手勢沖突,所以需要 

[singleTap requireGestureRecognizerToFail:doubleTap];在執行doubleTap的時候注銷掉singleTap

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~然后高潮來了~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我是可愛的分割線~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

最主要的操作是 doubleTap 和pinchGesture,這也是花了我最多時間的兩個問題

首先講一下doubleTap的思想,大家注意觀察微信的圖片瀏覽器,doubleTap在執行的時候會得到一個在View的點   CGPoint tapPoint = [doubletap locationInView:doubletap.view];

然后雙擊后,放大UIImageView,然后通過設定contentoffset偏移量將 tapPoint 移到屏幕最中間,這是雙擊的點包含在圖片里的情況,另外一種情況,是雙擊的點在圖片外,然后點在圖片外又有 左上,右上,左下,右下四種情況。分別將圖片放大然后,圖片左上,右上,左下,右下四個方向貼邊顯示

然后根據tapPoint的x,y判斷四種不同的情況 

 

tapX,tapY是tapPoint的x,y  imgY是圖片的y值,imgHeight是圖片的Height
if
(tapY<imgY) { //上面 pointType = XJAlbumOutImgViewPointLeftUp; if (tapX>myScreenWidth/2) { pointType = XJAlbumOutImgViewPointRightUp; } isOutImgView = YES; } else if(tapY>imgY+imgHeight) { //下面 pointType = XJAlbumOutImgViewPointLeftDown; if (tapX>myScreenWidth/2) { pointType = XJAlbumOutImgViewPointRightDown; } isOutImgView = YES; }

 

if (isOutImgView) {
                //如果點擊的是在圖片外面
                NSLog(@"isout");
                
                switch (pointType) {
                    case XJAlbumOutImgViewPointLeftUp:
                    {
                        singleScrollView.contentOffset = CGPointMake(0, 0);
                    }
                        break;
                    case XJAlbumOutImgViewPointLeftDown:
                    {
                        singleScrollView.contentOffset = CGPointMake(0, imgview.frame.size.height - myScreenHeight);
                    }
                        break;
                    case XJAlbumOutImgViewPointRightDown:
                    {
                        singleScrollView.contentOffset = CGPointMake(imgview.frame.size.width - myScreenWidth, imgview.frame.size.height - myScreenHeight);
                    }
                        break;
                    case XJAlbumOutImgViewPointRightUp:
                    {
                        singleScrollView.contentOffset = CGPointMake(imgview.frame.size.width - myScreenWidth, 0);
                    }
                        break;
                    default:
                    break;
                }
            }
            else
            {
                //將雙擊的點設置到屏幕的中心   先計算出點距圖片邊緣的距離,然后根據比例求出offsetX;       imgX,imgY 分別是圖片的 x,y 坐標值
                CGFloat offsetX = (tapX-imgX)*maxScale - myScreenWidth/2;
                CGFloat offsetY = (tapY-imgY)*maxScale - myScreenHeight/2;
                //如果超出最大范圍,則設置邊界值
                offsetY = offsetY<0?0:offsetY;
                offsetY = offsetY>imgview.frame.size.height-myScreenHeight?imgview.frame.size.height-myScreenHeight:offsetY;
                offsetX = offsetX<0?0:offsetX;
                offsetX = offsetX>imgview.frame.size.width - myScreenWidth?imgview.frame.size.width - myScreenWidth:offsetX;
                singleScrollView.contentOffset = CGPointMake(offsetX,offsetY);
            }
            isBigger = YES;

 

然后就是捏合手勢,捏合手勢 主要的兩點是 實時的根據放大的比例來改變 UIimageView的size , UIScrollView的contentSize,contentoffset

捏合手勢 pinchGesture的思想是 獲取手勢開始時,兩點的中心點,然后計算出 該中心點在屏幕中的相對位置 , 在手勢變化的時候,保持這個相對位置不改變。

// 變量offsetPinchX 是 scrollview 的 contentoffset.x   xInScreen 是 中心點在屏幕的相對位置,因為手勢獲取的點是相對手勢所在View上的相對位置,所以要減去 scrollview 的 x 偏移量

if (pinchGes.state == UIGestureRecognizerStateBegan) {

            

            oldFirstPoint = [pinchGes locationOfTouch:0 inView:pinchGes.view];

            oldSecondPoint = [pinchGes locationOfTouch:1 inView:pinchGes.view];

            oldLength = [self caculateLengthBetweenP1:oldFirstPoint P2:oldSecondPoint];

            //計算出初始中心點

            centrePoint = CGPointMake((oldFirstPoint.x+oldSecondPoint.x)/2,(oldSecondPoint.y+oldFirstPoint.y)/2);

            xInScreen = centrePoint.x - offsetPinchX;

        }

// minSize 是 初始的size   newSize 通過計算 兩個點之間的值的比例來獲得

  biggerScale = newLength/oldLength;

  newSize = CGSizeMake(oldSize.width*biggerScale,oldSize.height*biggerScale);

CGFloat newScale = newSize.width / minSize.width;
    
    // 算出 在屏幕的點
    
    if (newSize.width < maxSize.width && newScale>1) {
        offsetPinchX = xInScreen * (newScale - 1);
    }
    if (offsetPinchX<0) {
        offsetPinchX = 0;
    }
    if (offsetPinchX>(newSize.width - myScreenWidth)) {
        offsetPinchX = newSize.width - myScreenWidth;
    }
    NSLog(@"%f ------ %f ------%f",offsetPinchX,centrePoint.x,newScale);
    
    if (newSize.width == maxSize.width) {
        
    }
    else
    {
        singleScroll.contentOffset = CGPointMake(offsetPinchX, 0);
    }


 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM