swift图片浏览器

思路为一个scrollView上加3个scrollView进行重用,可接收url和本地图片,支持滑动浏览和缩放浏览,长按可保存原图到本地,单击退出,其他都没问题,有个bug“缩放一张后其他图片无法缩放”,待解决

-----更新-----

在写这篇文章的时候又试了一下,竟然把bug解决了,哈哈,我把图片缩放尺寸变成20倍,发现能多缩放几次后才不能缩放,于是就在每次缩放后用setZoomScale(1, animated: false),问题解决。因为scrollView进行了重用,更新图片后zoomScale没更新,缩放后zoomScale进行累加达到预设值后就不能再放大了。

一共两个文件 代码如下

import UIKit


class photoViewViewController: UIViewController , UIScrollViewDelegate {
    
    //接收图片数组,数组类型可以是url数组,image数组
    var isUrl = false
    var imgArr = NSMutableArray()
    
    //显示scrollView
    var scrollView = UIScrollView()
    
    //显示下标
    var sliderLabel = UILabel()

    //接收当前图片的序号,默认的是0
    var currentIndex : NSInteger = 0
    
    var _subViewList=NSMutableArray()
    
    //三张加载图片
    var imageMiddle:UIImage?
    var imageLeft:UIImage?
    var imageRight:UIImage?
    
    //三个scrollView
    var scrollViewLeft = SubScrollView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
    var scrollViewMiddle = SubScrollView(frame: CGRectMake(UIScreen.mainScreen().bounds.width, 0 , UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
    var scrollViewRight = SubScrollView(frame: CGRectMake(UIScreen.mainScreen().bounds.width*2, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
    
    //图片保存次数限制判断
    var isSave = false
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blackColor()
        self.initScrollView()
        self.addLabels()
        self.loadPhoto(currentIndex)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    //初始化大scrollView
    func initScrollView(){
        self.scrollView = UIScrollView.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
        self.scrollView.pagingEnabled = true
        self.scrollView.userInteractionEnabled = true
        self.scrollView.showsHorizontalScrollIndicator = false
        self.scrollView.delegate = self
        
        self.scrollView.contentSize = CGSizeMake(3 * (UIScreen.mainScreen().bounds.size.width), UIScreen.mainScreen().bounds.size.height)
        self.scrollView.contentOffset = CGPointMake(UIScreen.mainScreen().bounds.size.width, 0)
        self.view.addSubview(self.scrollView)
        
        let singleTap = UITapGestureRecognizer.init(target: self, action:Selector("handleSingleTap"))
        singleTap.numberOfTapsRequired = 1
        singleTap.numberOfTouchesRequired = 1
        self.scrollView.addGestureRecognizer(singleTap)
        
        let longPressSave = UILongPressGestureRecognizer(target: self, action:"saveImageJudge")
        scrollViewMiddle.addGestureRecognizer(longPressSave)
        
        self.scrollView.addSubview(scrollViewLeft)
        self.scrollView.addSubview(scrollViewRight)
        self.scrollView.addSubview(scrollViewMiddle)
        
        for (var i = 0;i < self.imgArr.count ; i++){
            _subViewList.addObject(NSNull)
        }
    }
    
    //三个scrollView分别加载图片
    func loadPhoto(index:NSInteger){
        if index<0 || index>=self.imgArr.count{
            return
        }
        //判断图片来源
        if isUrl == true{
            imageMiddle = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[index] as! String)!)!)
            if index == 0{
                imageLeft = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[imgArr.count-1] as! String)!)!)
                imageRight = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[index+1] as! String)!)!)
            }else if index == imgArr.count-1{
                imageLeft = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[index-1] as! String)!)!)
                imageRight = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[0] as! String)!)!)
            }else{
                imageLeft = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[index-1] as! String)!)!)
                imageRight = UIImage(data: NSData(contentsOfURL: NSURL(string: imgArr[index+1] as! String)!)!)
            }
        }else{
            imageMiddle = imgArr[index] as? UIImage
            if index == 0{
                imageLeft = imgArr[imgArr.count-1] as? UIImage
                imageRight = imgArr[index+1] as? UIImage
            }else if index == imgArr.count-1 {
                imageLeft = imgArr[index-1] as? UIImage
                imageRight = imgArr[0] as? UIImage
            }else{
                imageLeft = imgArr[index-1] as? UIImage
                imageRight = imgArr[index+1] as? UIImage
            }
            
        }
        
        scrollViewLeft.imageView.frame = CGRectMake(0, 0 , UIScreen.mainScreen().bounds.width ,UIScreen.mainScreen().bounds.width / imageLeft!.size.width*imageLeft!.size.height)
        scrollViewMiddle.imageView.frame = CGRectMake(0, 0 , UIScreen.mainScreen().bounds.width ,UIScreen.mainScreen().bounds.width / imageMiddle!.size.width*imageMiddle!.size.height)
        scrollViewRight.imageView.frame = CGRectMake(0, 0 , UIScreen.mainScreen().bounds.width ,UIScreen.mainScreen().bounds.width / imageRight!.size.width*imageRight!.size.height)
        
        scrollViewLeft.imageView.image = imageLeft
        scrollViewLeft.imageView.contentMode = UIViewContentMode.ScaleAspectFill
        scrollViewLeft.imageView.center.y = UIScreen.mainScreen().bounds.height/2
    
        scrollViewMiddle.imageView.contentMode = UIViewContentMode.ScaleAspectFill
        scrollViewMiddle.imageView.image = imageMiddle
        scrollViewMiddle.imageView.center.y = UIScreen.mainScreen().bounds.height/2

        scrollViewRight.imageView.contentMode = UIViewContentMode.ScaleAspectFill
        scrollViewRight.imageView.image = imageRight
        scrollViewRight.imageView.center.y = UIScreen.mainScreen().bounds.height/2
        
        //图片宽度都是固定的,若长度大于屏幕长度,要允许上下滑动查看
        if scrollViewLeft.imageView.bounds.height > UIScreen.mainScreen().bounds.height{
            scrollViewLeft.imageView.frame = CGRectMake(0, 0 , UIScreen.mainScreen().bounds.width ,UIScreen.mainScreen().bounds.width / imageLeft!.size.width*imageLeft!.size.height)
            scrollViewLeft.contentSize = CGSizeMake(scrollViewLeft.imageView.frame.width , scrollViewLeft.imageView.frame.height+1)
        }else{
            scrollViewLeft.contentSize = CGSizeMake(scrollViewLeft.imageView.frame.width , scrollViewLeft.imageView.frame.height)
        }
        
        if scrollViewMiddle.imageView.bounds.height > UIScreen.mainScreen().bounds.height{
            scrollViewMiddle.imageView.frame = CGRectMake(0, 0 , UIScreen.mainScreen().bounds.width ,UIScreen.mainScreen().bounds.width / imageMiddle!.size.width*imageMiddle!.size.height)
            scrollViewMiddle.contentSize = CGSizeMake(scrollViewMiddle.imageView.frame.width , scrollViewMiddle.imageView.frame.height+1)
        }else{
            scrollViewMiddle.contentSize = CGSizeMake(scrollViewMiddle.imageView.frame.width , scrollViewMiddle.imageView.frame.height)
        }
        
        if scrollViewRight.imageView.bounds.height > UIScreen.mainScreen().bounds.height{
            scrollViewRight.imageView.frame = CGRectMake(0, 0 , UIScreen.mainScreen().bounds.width ,UIScreen.mainScreen().bounds.width / imageRight!.size.width*imageRight!.size.height)
            scrollViewRight.contentSize = CGSizeMake(scrollViewRight.imageView.frame.width , scrollViewRight.imageView.frame.height+1)
        }else{
            scrollViewRight.contentSize = CGSizeMake(scrollViewRight.imageView.frame.width , scrollViewRight.imageView.frame.height)
        }
    }
    
    //截图次数限制,不然长按会自动保存两次,bug来源不明
    func saveImageJudge(){
        if isSave == false{
            self.saveImage()
            isSave = true
        }else {
            isSave = false
        }
    }
    
    //保存图片
    func saveImage(){
        UIImageWriteToSavedPhotosAlbum(scrollViewMiddle.imageView.image!, self, "image:didFinishSavingWithError:contextInfo:", nil)
    }
    
    func image(image: UIImage, didFinishSavingWithError error: NSError?,contextInfo:UnsafePointer<Void>){
        if let ee = error{
            print(ee)
        }else{
            let alertVC = UIAlertController(title: "", message: "保存成功!", preferredStyle: .Alert)
            let actionItem = UIAlertAction(title: "确定", style: .Default, handler: nil)
            alertVC.addAction(actionItem)
            self.presentViewController(alertVC, animated: true, completion: nil)
            
        }
    }

    //单击后退出当前视图
    func handleSingleTap(){
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    
    //添加计数标签
    func addLabels(){
        self.sliderLabel = UILabel.init(frame: CGRectMake(40, UIScreen.mainScreen().bounds.size.height-64-49, 60, 30))
        self.sliderLabel.backgroundColor = UIColor.clearColor()
        self.sliderLabel.textColor = UIColor.whiteColor()
        self.sliderLabel.text = NSString(format: "%ld/%lu", currentIndex+1,self.imgArr.count) as String
        self.view.addSubview(self.sliderLabel)
    }
    
    //向右滑动时重新加载图片
    func reloadPhotoLeft(index:NSInteger){
        if index == imgArr.count-1{
            return
        }else{
            loadPhoto(index+1)
            currentIndex+=1
        }
    }
    
    //向左滑动时重新加载图片
    func reloadPhotoRight(index:NSInteger){
        if index == 0{
            return
        }else{
            loadPhoto(index-1)
            currentIndex-=1
        }
    }
    
    //结束滑动并滑动超过一半时自动更新图片和标签 setZoomScale必须要重新设置为1,不然会有图片无法缩放的bug. 因为scrollView重用,scale会累加,到达预设值后不能再继续放大
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        if scrollView.contentOffset.x > UIScreen.mainScreen().bounds.width*1.5{
            self.scrollViewLeft.setZoomScale(1, animated: false)
            self.scrollViewMiddle.setZoomScale(1, animated: false)
            self.scrollViewRight.setZoomScale(1, animated: false)
            reloadPhotoLeft(currentIndex)
            scrollView.contentOffset.x = UIScreen.mainScreen().bounds.width
            self.sliderLabel.text = NSString(format: "%ld/%lu", currentIndex+1,self.imgArr.count) as String
        }
        
        if scrollView.contentOffset.x < UIScreen.mainScreen().bounds.width*0.5{
            self.scrollViewLeft.setZoomScale(1, animated: false)
            self.scrollViewMiddle.setZoomScale(1, animated: false)
            self.scrollViewRight.setZoomScale(1, animated: false)
            reloadPhotoRight(currentIndex)
            scrollView.contentOffset.x = UIScreen.mainScreen().bounds.width
            self.sliderLabel.text = NSString(format: "%ld/%lu", currentIndex+1,self.imgArr.count) as String
        }
    }
    
    //防止循环轮播
    func scrollViewDidScroll(scrollView: UIScrollView) {
        if currentIndex == (imgArr.count-1){
            if self.scrollView.contentOffset.x >= (UIScreen.mainScreen().bounds.width+1){
                self.scrollView.contentOffset.x = UIScreen.mainScreen().bounds.width
                self.scrollView.scrollEnabled = false
            }
        }
        if currentIndex == 0{
            if self.scrollView.contentOffset.x <= UIScreen.mainScreen().bounds.width-1{
                self.scrollView.contentOffset.x = UIScreen.mainScreen().bounds.width
                self.scrollView.scrollEnabled = false
            }
        }
    }
    
    //拖动结束后允许继续拖动
    func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
         self.scrollView.scrollEnabled = true
    }
}

  

import UIKit

class SubScrollView: UIScrollView,UIScrollViewDelegate {
    var imageView = UIImageView()
    override init(frame: CGRect) {
        super.init(frame:frame)
        self.delegate = self
        self.minimumZoomScale = 1
        self.maximumZoomScale = 2
        self.showsHorizontalScrollIndicator = false
        self.showsVerticalScrollIndicator = false
        self.userInteractionEnabled = true
        self.bounces = false
        self.scrollEnabled = true
        
        self.addSubview(imageView)
        self.setZoomScale(1, animated: true)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return self.imageView
    }
    
    func scrollViewDidZoom(scrollView: UIScrollView) {
        //根据不同图片长宽的情况设置contentsize
        if self.imageView.bounds.height > UIScreen.mainScreen().bounds.height{
            
            self.imageView.frame = CGRectMake(0, 0 , self.imageView.frame.width ,self.imageView.frame.height)
            self.contentSize = CGSizeMake(self.imageView.frame.width , self.imageView.frame.height+1)
        }else if self.imageView.bounds.height*2 < UIScreen.mainScreen().bounds.height{
            self.imageView.frame = CGRectMake(0, (UIScreen.mainScreen().bounds.height - self.imageView.frame.height)/2,self.imageView.frame.width ,self.imageView.frame.height)
            self.contentSize = CGSizeMake(self.imageView.frame.width , self.imageView.frame.height+1)
        }
        else{
            self.imageView.frame = CGRectMake(0, 0 , self.imageView.frame.width ,self.imageView.frame.height)
            self.contentSize = CGSizeMake(self.imageView.frame.width , self.imageView.frame.height+1)
        }
    }
    
    func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
        //长度小于屏幕宽度的图片放大缩小后回归中心
        if self.imageView.frame.height <= UIScreen.mainScreen().bounds.height && self.zoomScale == 1{
            self.imageView.center.y = self.center.y
        }
    }
}

  

posted @ 2016-03-25 17:39  torrescx  阅读(532)  评论(0编辑  收藏  举报