iOS中UIScrollView嵌套UIImageView实现图片滑动浏览、缩放

一开始的时候是UIScrollView直接嵌套UIImageView,滑动浏览都是正常的,但是不能伸缩,试了UIScrollVIew自身的zoom方法,也试用了pinch gesture的方法都无果,后来想到了用UIScrollView嵌套UIScrollVIew再嵌套UIImageView的方法实现,然后缩放用的是UIScrollView自身的缩放方法,成功,很棒。

载入图片是用的SDWebImage,提示框用的是MBProgressHUD

实现了在当前图片放大情况下,滑动到相邻的图片时对当前图片恢复到原始比例。以及缩小时保证图片在正中间。解决了滑动时显示多个“载入中”的BUG

以下是源码:(直接复制不能运行)

    func showImages(theView:UIView,imageNamesTMP:[String])
    {
        println("showImages")
        imageNames = imageNamesTMP
                
        var numberOfImages:CGFloat = (CGFloat)(imageNames.count)
        
        
        
        imageBigScrollView.contentSize = CGSizeMake(SCREENWIDTH * numberOfImages, SCREENHEIGHT)
        
        imageSmallScrollViews = NSMutableArray()
        for(var i = 0; i < (Int)(numberOfImages);i++)
        {

            var smallScrollView = UIScrollView(frame: CGRectMake(SCREENWIDTH * (CGFloat)(i), 0, SCREENWIDTH, SCREENHEIGHT))
            smallScrollView.pagingEnabled = false
            smallScrollView.contentSize = CGSizeMake(SCREENWIDTH, SCREENHEIGHT)
            smallScrollView.delegate = self
            smallScrollView.showsHorizontalScrollIndicator = false
            smallScrollView.showsVerticalScrollIndicator = false
            smallScrollView.minimumZoomScale = 0.2
            smallScrollView.maximumZoomScale = 8
            

            imageBigScrollView.addSubview(smallScrollView)
            imageSmallScrollViews.addObject(smallScrollView)
        }
        
        
        var pageControlHeight:CGFloat = 20

        imagePageControl = UIPageControl(frame: CGRectMake(0, SCREENHEIGHT - pageControlHeight, SCREENWIDTH, pageControlHeight))

        theView.addSubview(imagePageControl)

        var longGesture = UILongPressGestureRecognizer(target: self, action: "longPressed:")
        imageBigScrollView.addGestureRecognizer(longGesture)
        
        
        imagePageControl.numberOfPages = (Int)(numberOfImages)
        imagePageControl.currentPage = 0
        imagePageControl.backgroundColor = UIColor.clearColor()
        imagePageControl.hidesForSinglePage = true
        imagePageControl.defersCurrentPageDisplay = true
        needToZoomIndex = imagePageControl.currentPage
        
        imageViews = NSMutableArray()
        imageFlag = NSMutableArray()
        
        for(var i = 0; i < imageNames.count; i++)
        {
            imageViews.addObject(UIImageView())
            imageFlag.addObject(0)
        }
        loadImageWithPage(0)
        loadImageWithPage(1)
    }
    func loadImageWithPage(page:Int)
    {
        if(page < 0 || page >= imageNames.count)
        {
            return
        }
        
        var flag = imageFlag.objectAtIndex(page) as Int
        var iView:UIImageView = imageViews.objectAtIndex(page) as UIImageView
        
        if(flag == 0)
        {
            
            var frame = self.imageBigScrollView.frame
            frame.origin.x = 0
            frame.origin.y = 0
            
            iView.userInteractionEnabled = true
            iView.frame = frame
            iView.contentMode = UIViewContentMode.ScaleAspectFit
            (self.imageSmallScrollViews.objectAtIndex(page) as UIScrollView).addSubview(iView)
            println("add one image:\(page)")
            var hud:SMS_MBProgressHUD = SMS_MBProgressHUD.showMessagManually("载入中", toView: iView)
            self.imageFlag.replaceObjectAtIndex(page, withObject: 1)
            
            iView.sd_setImageWithPreviousCachedImageWithURL(NSURL(string: imageNames[page]), andPlaceholderImage: nil, options: SDWebImageOptions.ProgressiveDownload, progress: { (a, b) -> Void in
//                println("\(page): \(b)")
//                hud.progress = (Float)(a)/(Float)(b)
                
                
            }, completed: { (tmpImage, err, cachType, url) -> Void in
                hud.hide(true)
                println("pic \(page) load complete")
                if let error = err
                {
                    
                }
                else
                {
                    self.imageFlag.replaceObjectAtIndex(page, withObject: 1)
                    self.imageViews.replaceObjectAtIndex(page, withObject: iView)
                    
                    
//                    iView.image.set
                    
                    
                    
                    
                    //                CGRectMake(frame.size.width * (CGFloat)(page), (SCREENHEIGHT - image.size.height * SCREENWIDTH / image.size.width)/2, SCREENWIDTH, image.size.height * SCREENWIDTH / image.size.width)
//                    println(frame.width)
                    
                }
                
            })
            
        }
        
        
    }
    func scrollViewDidScroll(scrollView: UIScrollView) {
        if(pageControlUsed == true)
        {
            return
        }
        
        var pageWidth = imageBigScrollView.frame.size.width
        var page:Int = (Int)(floor((imageBigScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
        imagePageControl.currentPage = page
        
        self.loadImageWithPage(page - 1)
        self.loadImageWithPage(page)
        self.loadImageWithPage(page + 1)
        
        if(page != lastPageIndex)
        {
            setZoomToOne(lastPageIndex)
            lastPageIndex = page
        }
    }
    
    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        pageControlUsed = false
    }
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        pageControlUsed = false
    }
    
    func setZoomToOne(page:Int)
    {
        
        if(page < 0 || page >= imageNames.count || lastSetIndex == page)
        {
            return
        }
        println("set:\(page) \(lastPageIndex)")
        lastSetIndex = page
        
        needToZoomIndex = page
        (imageSmallScrollViews.objectAtIndex(page) as UIScrollView).setZoomScale(1, animated: true)
        needToZoomIndex = imagePageControl.currentPage
    }
    
    func tapPressed(sender:UITapGestureRecognizer)
    {

        self.dismissViewControllerAnimated(true, completion: nil)
    }
    func longPressed(sender:UILongPressGestureRecognizer)
    {
        
        println("\(imagePageControl.currentPage)")
        if(imagePageControl.currentPage != lastLongPressIndex)
        {
            lastLongPressIndex = imagePageControl.currentPage
            UIActionSheet(title: "选择" , delegate: self, cancelButtonTitle: nil, destructiveButtonTitle: nil, otherButtonTitles: "保存图片","取消").showInView(self.view)
        }
        else
        {
            lastLongPressIndex = -1
        }
    }
    func pinchPressed(sender:UIPinchGestureRecognizer)
    {
        println("pinch")
        var iView:UIImageView = imageViews.objectAtIndex(imagePageControl.currentPage) as UIImageView
        if(sender.state == UIGestureRecognizerState.Began)
        {
            beganScale = (imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView).zoomScale
        }
        (imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView).setZoomScale(beganScale * sender.scale, animated: true)
        
        
        if(sender.state == UIGestureRecognizerState.Ended)
        {
            
            scrollViewEnd()
        }
        
    }
    func scrollViewEnd()
    {
//        println("end")
        var isv = imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView
        if(isv.zoomScale < 1.0)
        {
            println("set back 1")
            isv.setZoomScale(1, animated: true)
        }
        else if(isv.zoomScale > 2.0)
        {
            isv.setZoomScale(2.0, animated: true)
        }
        
        
    }
    
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
//        println("view for zoom")
        return imageViews.objectAtIndex(needToZoomIndex) as UIImageView
    }
    func scrollViewDidZoom(scrollView: UIScrollView) {
        var iView:UIImageView = imageViews.objectAtIndex(imagePageControl.currentPage) as UIImageView
        var isv = imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView
        if(isv.zoomScale < 1.0)
        {
            isv.contentOffset = CGPointMake(-(isv.frame.width - iView.frame.size.width) / 2, -(isv.frame.height - iView.frame.size.height) / 2)
            
        }
    }
    func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) {
        scrollViewEnd()
    }
    
    func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
        println("actionsheet:\(buttonIndex)")
        if(buttonIndex == 0)
        {
            UIImageWriteToSavedPhotosAlbum((imageViews.objectAtIndex(imagePageControl.currentPage) as UIImageView).image, self, "imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:", nil)
        }
    }
    func imageSavedToPhotosAlbum(image:UIImage, didFinishSavingWithError error:NSError?, contextInfo:AnyObject)
    {
        if let err = error
        {
            SMS_MBProgressHUD.showError("保存失败", toView: self.view)
        }
        else
        {
            SMS_MBProgressHUD.showCompleteMessage("保存成功", toView: self.view)
        }
    }

    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


你可能感兴趣的:(uiimageview,uiscrollview,swift,ios)