思路为一个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 } } }