通过一个关于相册浏览的简单应用--图片缩放,垂直滑动图片,翻页效果,大家将学到UIScrollView相关的知识。
#1 UIScrollView是什么
1.UIScrollView是所有滚动视图的基类,子类有UITableView和UICollectionView,是iOS开发中最常用的组件
2.UIScrollView是UIKit中为数不多响应滑动手势的View
使用场景:显示不下(单张大图),内容太多(图文混排),滚动头条(图片),相册等
3.UIScrollView专长于两个方面:滚动和缩放(zoom in && zoom out)
#2 UIScrollViewDelegate
是什么?UIScrollViewDelegate是UIScrollView的delegate protocol,UIScrollView的功能是通过它的代理方法实现的
以后我会补充的...
#3 UIScrollView和auto layout
UIScrollView和auto layout总的来说就一个原则,必须完全定义contentSize。
1.UIScrollView的contentSize属性
contentSize表示UIScrollView可滚动内容的大小,由UIScrollView的subview的约束来决定。
2.对于UIScrollView的subview来说,它的约束是相对于UIScrollView的contentSize来说,而不是bounds。
3.Scrollable Content Size Ambiguity问题
什么时候会出现?用scrollView和它的subview的约束来互相决定大小时。
什么意思?scrollView的subview希望以contentSize为参照来确定自己的尺寸,但是contentSize又由subview的约束来确定。最后导致的就是,auto layout不知道到底谁来决定谁,不知道如何确定两者的尺寸。
如何解决?两种方案。
--用UIScrollView的width和height 来决定subview的尺寸
--用UIScrollView和view之间的约束来决定subview的尺寸
当然,如果嫌麻烦的话,在UIScrollView和UILabel间增加一个UIView,上下左右约束均为0,以保证覆盖scrollView,另外还要给它加宽度和高度约束,以完全定义contentSize。
#4 项目练习
下载UIScrollView材料
放大图片的实现
1.将UIScrollView拖动到Zoomed Photo View Controller里,为scrollView添加约束,上下左右的间距均为0,为image view添加相同的约束。
2.添加outlet属性,并将这些属性与storyboard里Zoomed Photo View Controller关联起来。
3.添加代理方法, imageView将随UIScrollView而扩大。
需要注意的是,返回storyboard里,将delegate连接到scrollView上。
4.计算并更新scrollView的最小缩放比例。
你需要考虑,为了扩大imageView,scrollView应缩小多大比例,才能让imageView刚好fit ScrollView的bounds。
问题一:如何计算最小缩放比例?取宽度缩放比例和高度缩放比例的最小值。而要想计算宽度缩放比例,因为scrollView这里应该缩小,所以size.width应该小于imageView.bounds.width,所以size.width应在分子位置上。
问题二:这里为什么不计算最大缩放比例?
scrollView的minimumZoomScale,maxZoomScale,zoomScale的默认值都是1.在这个地方,scrollView是缩小,当然考虑的是它的下限--最小缩放比例。
问题三:为什么用的是bounds而不是frame?
bounds是相对于subview而言的。
5.更新image view的约束。
为了让scrollView缩小后,imageView还是能固定在center,这里需要对imageView的前后约束加以限制。注意,这里用的是frame,不是bounds,因为这里是相对于父视图而言的。
用yOffset和xOffset来共同确定contentOffset--视图左上角距离坐标原点的偏移量
垂直滑动图片的实现
1.拖控件
--拖一个View Controller出来,命名为PhotoComment View Controller,在Attributes Inspector里,不要勾选Adjust ScrollView Insets,以方便一会手动设置scrollview的insets
--分别拖一个scrollView和view出来,view设为scrollView的child。给这两个view加约束,上下左右的间隔均为0。把view命名为containerView,给它的宽高加约束,containerView.width = superview.width,container.height = 500.
--拖一个imageView,label和textField出来。加约束。
2.建立segue
去掉Photo Scroll View Controller和Zoomed Photo View Controller之间的segue,建立Photo Scroll View Controller和PhotoComment View Controller之间的segue,Identifier命名为“showPhotoPage”
3.将storyboard与代码关联起来,并通过photoName来set imageView的image。
4.在CollectionViewController.swift里,添加prepareForSegue方法。当选中photo时,能将照片的名字set在PhotoComment View Controller上。
5.处理键盘弹起和消失所带来的scrollView的高度变化
需要解释的是adjustInsetForKeyboardShow方法
(1)先得到notification中userInfo字典里keyboardFrame的值(NSValue类)
(2)将这个值转为CGRect类
(3)计算scrollView应该调整的高度。如果键盘显示,adjustmentHeight = keyboardFrame+20,如果键盘不显示,就恢复原样。
(4)计算scrollView的contentInset和scrollIndicatorInsets的底部位置
6.点击空白处,隐藏键盘
--添加方法
--拖一个Tap Gesture Recognizer到PhotoComment View Controller的root view controller里,与此方法关联,并且也要和view关联
翻页效果的实现
1.在storyboard里,拖动一个UIPageViewController,在Attributes Inspector里,把Transition Style修改为Scroll,Page Spacing设置为8,storyboard ID设为PageViewController,另外把PhotoCommentViewController的storyboard ID设为PhotoCommentViewController。
2.在PhotoCommentViewController.swift里添加以下代码,指明photo的index。
3.新建一个文件,subclass of UIPageViewController,并命名为ManagePageViewController,并在storyboard中做相应地工作
(1)添加数组和当前索引
(2)搭建ManagePageViewController
--添加一个方法。此方法的作用在于:创建一个PhotoCommentViewController的实例page,并把ManagePageViewController中的name,index传给这个实例。
--搭建ManagePageViewController。思路是:它由5个PhotoCommentViewController型的viewcontroller组成,所以先要调用上面的方法创建一个PhotoCommentViewController的实例,再创建这样的数组,最后调用setViewControllers方法搭建ManageViewController。在viewDidLoad方法里添加代码
(3)添加两个数据源方法,向前滑动和向后滑动的时候content能相应地呈现出来。需要解释的是:
--UIPageViewControllerDataSource让页面变化的时候,内容能够相应地呈现出来。
--参数viewController显示的是当前显示的页面
向前滑动,创建一个PhotoCommentViewController类的实例viewController,在保证index不为0(不是第一个页面)且找得到的情况下,调用viewPhotoCommentController方法创建一个新的实例,作为前一个页面。
向后滑动,index的条件变成index找得到且index不是最后一个页面。
4.处理转场
--删掉之前的showPhotoPage转场,添加Scroll View Controller到Manage Page View Controller之间的segue,并把这个segue的Identifier命名为“showPhotoPage”
--在转场前,做一些准备。把Scroll View Controller的row属性和photos存入ManagePage View Controller的currentIndex和photos属性中。
5.显示Page Control Indicator
--添加UIPageControl的两个方法。告诉page view controller显示的页的数目,以及当前显示哪一页。
--自定义PageControl
6.将ZoomedPhotoViewController添加进来
(1)在PhotoCommentViewController.swift里添加两个方法,点击imageView的时候,能够转到ZoomedPhotoViewController。在转场前把PhotoCommentViewController的photoName存入ZoomedPhotoViewController中。
(2)在storyboard里,建立PhotoCommentViewController和ZoomedViewController之间的segue,segue命名为“zoom”。
将PhotoCommentViewController里的image view选中,勾选User Interaction Enabled。
添加Tap Gesture Recognizer,并与openZoomedViewController方法和imageView关联。
终于,项目完成了!!!
参考博客:
UIScrollView Tutorial: Getting Started
ScrollView 与 Autolayout - Nonomori - Let monkeys coding for iOS