相册浏览的简单应用(UIScrollView)

通过一个关于相册浏览的简单应用--图片缩放,垂直滑动图片,翻页效果,大家将学到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和view之间的约束来决定subview的尺寸

当然,如果嫌麻烦的话,在UIScrollView和UILabel间增加一个UIView,上下左右约束均为0,以保证覆盖scrollView,另外还要给它加宽度和高度约束,以完全定义contentSize。

#4 项目练习

下载UIScrollView材料

放大图片的实现

1.将UIScrollView拖动到Zoomed Photo View Controller里,为scrollView添加约束,上下左右的间距均为0,为image view添加相同的约束。

添加UIScrollView和相应的约束

2.添加outlet属性,并将这些属性与storyboard里Zoomed Photo View Controller关联起来。

ZoomPhotoViewController.swift

3.添加代理方法, imageView将随UIScrollView而扩大。

需要注意的是,返回storyboard里,将delegate连接到scrollView上。

添加代理方法

4.计算并更新scrollView的最小缩放比例。

你需要考虑,为了扩大imageView,scrollView应缩小多大比例,才能让imageView刚好fit ScrollView的bounds。

计算并更新scrollView的最小缩放比例

问题一:如何计算最小缩放比例?取宽度缩放比例和高度缩放比例的最小值。而要想计算宽度缩放比例,因为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--视图左上角距离坐标原点的偏移量

为imageView的leading和trailing constraint计算offset
在缩放后,更新约束


垂直滑动图片的实现

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出来。加约束。

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。

PhotoComment View Controller.swift

4.在CollectionViewController.swift里,添加prepareForSegue方法。当选中photo时,能将照片的名字set在PhotoComment View Controller上。

CollectionViewController.swift

5.处理键盘弹起和消失所带来的scrollView的高度变化

PhotoCommentViewController.swift

需要解释的是adjustInsetForKeyboardShow方法

(1)先得到notification中userInfo字典里keyboardFrame的值(NSValue类)

(2)将这个值转为CGRect类

(3)计算scrollView应该调整的高度。如果键盘显示,adjustmentHeight  = keyboardFrame+20,如果键盘不显示,就恢复原样。

(4)计算scrollView的contentInset和scrollIndicatorInsets的底部位置

6.点击空白处,隐藏键盘

--添加方法

PhotoCommentViewController.swift

--拖一个Tap Gesture Recognizer到PhotoComment View Controller的root view controller里,与此方法关联,并且也要和view关联 

Tap Gesture Recognizer

翻页效果的实现

1.在storyboard里,拖动一个UIPageViewController,在Attributes Inspector里,把Transition Style修改为Scroll,Page Spacing设置为8,storyboard ID设为PageViewController,另外把PhotoCommentViewController的storyboard ID设为PhotoCommentViewController。

2.在PhotoCommentViewController.swift里添加以下代码,指明photo的index。

PhotoCommentViewController.swift

3.新建一个文件,subclass of UIPageViewController,并命名为ManagePageViewController,并在storyboard中做相应地工作

(1)添加数组和当前索引

ManagePageViewController.swift

(2)搭建ManagePageViewController

--添加一个方法。此方法的作用在于:创建一个PhotoCommentViewController的实例page,并把ManagePageViewController中的name,index传给这个实例。

ManagePageViewController.swift

--搭建ManagePageViewController。思路是:它由5个PhotoCommentViewController型的viewcontroller组成,所以先要调用上面的方法创建一个PhotoCommentViewController的实例,再创建这样的数组,最后调用setViewControllers方法搭建ManageViewController。在viewDidLoad方法里添加代码

ManagePageViewController.swift

(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属性中。

CollectionViewController.swift

5.显示Page Control Indicator

--添加UIPageControl的两个方法。告诉page view controller显示的页的数目,以及当前显示哪一页。

ManagePageViewController.swift

--自定义PageControl

AppDelegate.swift

6.将ZoomedPhotoViewController添加进来

(1)在PhotoCommentViewController.swift里添加两个方法,点击imageView的时候,能够转到ZoomedPhotoViewController。在转场前把PhotoCommentViewController的photoName存入ZoomedPhotoViewController中。

PhotoCommentViewController.swift

(2)在storyboard里,建立PhotoCommentViewController和ZoomedViewController之间的segue,segue命名为“zoom”。

将PhotoCommentViewController里的image view选中,勾选User Interaction Enabled。

添加Tap Gesture Recognizer,并与openZoomedViewController方法和imageView关联。

终于,项目完成了!!!

参考博客:

UIScrollView Tutorial: Getting Started

UIScrollView 实践经验

ScrollView 与 Autolayout - Nonomori - Let monkeys coding for iOS

UIScrollView属性及其代理方法 - 简书

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 我大体对某一个时间节点,一群人接近疯狂的抢购某种东西毫不感冒,况且网络上各种红包返券让人看了就头疼,我数学不好,线...
    summershine阅读 714评论 0 3
  • 当第一次收到这張照片的时候,我震惊了,“娛樂場的客人因为一把投注了360萬。自己八點输庄家九點,血气攻心,晕倒在地...
    安亲阅读 374评论 2 0
  • 今年有两部日剧是做到刷屏的,一部是早前的《我的危险妻子》,另一部就是这周刚完结的《贤者之爱》。细想一下,这两部片子...
    悲观主义的花朵FOP阅读 436评论 0 0
  • 前几天被好友问起最喜欢的食物,我想都没想说,当然是……说到一半忽然卡克了。如果问起我喜欢吃什么,绝对可以如数家...
    猫小埋阅读 196评论 0 0