来源: http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift
UIScrollView是iOS当中最多样和有用的控件之一。它是非常主流的UITableView的基础并且是一种非常好的方式来展现比单屏大的内容。在这篇教程当中你将学习所有关于使用这个控件:
怎么使用UIScrollView来查看一个很大的图片
在缩放中怎么保持UIScrollView的内容是居中的
怎样嵌入一个非常负载的层级进入UIScrollView
怎么样使用UIScrollView的页面特性,和UIPageControl的连接,使得滑动多页面的内容
怎么制作一个”瞥一眼“的UIScrollView,方便快速浏览之前的下页的以及当前页的内容(有点纠结。。。)
还有更多内容
这篇教程假定你已经对Swift和iOS编程有一定的熟悉程度了。如果你是一个完全的新手,你最好先学习一下其他的基础教程。
这篇教程当然也假定你已经知道了怎么使用Interface Builder来添加新的对象到view并且知道连outlets在你的代码和Storyboard(网站这里还拼错了。。)之间。在继续之前你应该要熟悉Storyboards,如果你对Storyboards和Interface Builder很陌生的话最好先浏览一下Storyboard教程。
这一部分基本没有很大翻译的必要,对照网站看图片一步步实现就好了,重点将在下面代码实现和分析的部分
你现在首要学习的是怎样建立一个 scroll view
能让用户缩放一个图片并且各种滑动。
首先,你需要建一个 view controller
。打开 ViewController.swift
,然后在文件的头部改变类的定义,当然它需要遵循 UIScrollViewDelegate
协议。
class ViewController: UIViewController, UIScrollViewDelegate {
在类声明内容,添加如下outlet属性
@IBOutlet var scrollView: UIScrollView!
在下一步你将会链接scroll view。
打开storyboard然后拽入一个从 objects library 中拽入View Controller。选择这个新的 view controller 然后在 Identity Inspector
中,把 Class
设置为 ViewController
。
这个 view controller 会显示一个 image scroll demo。按住 Control
键然后从 table view 中的 Image Scroll
的那一行拽进这个新的 view controller。在显示的弹出目录中,在 Selection Segue
下选择 Push
。这样会链接它们因此当用户点击了第一个 row 的时候,这个view controller 会被压入导航栈之中。
从 object library 中拽一个 Scroll View
完全铺满放入 view controller。
现在是时候来写代码了。打开 ViewController.swift
然后添加一个新的属性:
var imageView: UIImageView!
这个可以持有用户滑动的图片
现在是时候来到设置 scroll view 最有趣的时候了。用以下代码来替换 viewDidLoad
之中的代码。
override func viewDidLoad() { super.viewDidLoad() // 1 let image = UIImage(named: "photo1.png")! imageView = UIImageView(image: image) imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size:image.size) scrollView.addSubview(imageView) // 2 scrollView.contentSize = image.size // 3 var doubleTapRecognizer = UITapGestureRecognizer(target: self, action: "scrollViewDoubleTapped:") doubleTapRecognizer.numberOfTapsRequired = 2 doubleTapRecognizer.numberOfTouchesRequired = 1 scrollView.addGestureRecognizer(doubleTapRecognizer) // 4 let scrollViewFrame = scrollView.frame let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height let minScale = min(scaleWidth, scaleHeight); scrollView.minimumZoomScale = minScale; // 5 scrollView.maximumZoomScale = 1.0 scrollView.zoomScale = minScale; // 6 centerScrollViewContents() }
这个看起来比较复杂,所以我们一步步来分析。你会看到这个并不是那么可怕。
首先,你要创建一个名为 photo1.png
的 image view。然后这里强制解包表示如果工程不能找到 photo1.png
这张图片程序就会崩溃,这个可以让你更早的发现问题如果你忘记放入图片了!下一步,你要设置 image view 的 frame(它的尺寸和位置)用来把它放在父视图(0,0)位置。最后,把 image view 作为子视图放入 scroll view 当中。
你必须要告诉 scroll view 内容的 size,当它知道以后就可以得出滑动的横向和纵向距离。在这个例子中,它是图片的尺寸大小。
这里你需要设置一个双击手势来放大图片。你不需要设置一个 UIPinchGestureRecognizer
来缩放,因为 UIScrollView
已经自带了一个!
接下来,你需要算出 scroll view 的最小缩放比例。1的缩放比例表示内容是正常尺寸,小于1的缩放比例表示内容缩小,大于1的缩放比例表示内容放大。为了得到最小的缩放比例,你要计算出图片基于它的宽度来缩小使得图片能够合适的适配你的 scroll view 的边界。然后基于高度做同样的事情。这两个结果的最小值作为 scroll view 的最小缩放比例。这样的缩放比例可以使得当你完全缩小图片的时候,你可以看到整张图片。
你设置最大缩放比例为1,因为设置过大的时候可能会导致图片模糊。你设置最初的缩放比例为最小的,这样图片开始就是最小缩放状态。
这句代码能让 scroll view 居中图片。这个方法在哪里?接下来实现它!
func centerScrollViewContents() { let boundsSize = scrollView.bounds.size var contentsFrame = imageView.frame if contentsFrame.size.width < boundsSize.width { contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0 } else { contentsFrame.origin.x = 0.0 } if contentsFrame.size.height < boundsSize.height { contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0 } else { contentsFrame.origin.y = 0.0 } imageView.frame = contentsFrame }
这个方法对于 UIScrollView
有轻微的作用:如果 scroll view 的 contentSize
比它的 bounds
还小,那么就把它放在左上角而不是居中。因为你允许用户完全缩小图片,如果图片放在正中间将会变得非常友好。这个方法实现了把 image view 始终放置在 scroll view 的中间。
最后,把双击点击手势的方法 scrollViewDoubleTapped
添加进入类。
func scrollViewDoubleTapped(recognizer: UITapGestureRecognizer) { // 1 let pointInView = recognizer.locationInView(imageView) // 2 var newZoomScale = scrollView.zoomScale * 1.5 newZoomScale = min(newZoomScale, scrollView.maximumZoomScale) // 3 let scrollViewSize = scrollView.bounds.size let w = scrollViewSize.width / newZoomScale let h = scrollViewSize.height / newZoomScale let x = pointInView.x - (w / 2.0) let y = pointInView.y - (h / 2.0) let rectToZoomTo = CGRectMake(x, y, w, h); // 4 scrollView.zoomToRect(rectToZoomTo, animated: true) }
这个方法当被双击的时候会触发。接下来就是一步步分析代码:
首先,你需要得到是在 image view 中的哪里点击的。你将基于这个点来放大图片,你可以想象你是一个用户。
接下来,你计算1.5倍的缩放比例,但是要和 scroll view 的最大缩放比例做一个比较,取得最小值。
然后你需要用到步骤1当中的点来计算一个 CGRect
矩形用来放大。
最后,你需要告诉 scroll view 去放大,当然你需要一个动画效果来让它感觉起来不错。
获得更多关于iOS手势的信息,浏览相关教程 UIGestureRecognizer tutorial
现在,还记得你设置 ViewController
遵循 UIScrollViewDelegate
协议吗?好的,现在你需要实现一些必须的代理方法。添加如下方法到类中。
func viewForZoomingInScrollView(scrollView: UIScrollView!) -> UIView! { return imageView }
这个是 scroll view 缩放的核心与灵魂。你要告诉控制器是当你捏合的时候是哪一个 view 需要被放大和缩小。所以,你需要告诉它是你的 imageView
。
最后,添加这个代理方法。
func scrollViewDidZoom(scrollView: UIScrollView!) { centerScrollViewContents() }
这个方法会在用户结束缩放的时候调用。这里,你需要重新居中 view,如果没有,scroll view 不会展现的很自然;相反,可能会偏向左上角。
现在,深呼吸一下,调整一下自己然后编译并运行你的工程!点击 Image Scroll
如果它显示的很流畅,你可以得到一个好的图片可以让你缩放,捏合和点击!
本系列翻译属于个人兴趣,不作任何其他用途,如有任何版权信息问题,请联络本人做相关处理,谢谢!
感谢原文来源网站: www.raywenderlich.com