引导
“ 本文不适合老司机… ”Copyright © PBWln Unauthorized shall not be reproduced.
本文章将介绍 iOS UI控件 详解,最常使用的三大控件之一 UIScrollView,将会分成两篇文章完整的讲述
UIScrollView的常用属性方法使用(包括优化方面)及注意点 和 实战开发使用场景案例,文章编写周期会长一些,用到那点实用的东西,会及时补充。
本篇文章主要从【 UIScrollView 属性方法注解】学习总结。
在「时间 & 知识 」有限内,总结的文章难免有「未全、不足 」的地方,还望各位好友指出,以提高文章质量。
目录:
- UIScrollView概念
- UIScrollView基本使用(滚动)
- UIScrollView属性与方法
1.属性 & 方法
2.使用格式 & 说明:
3.简明注解:- UIScrollView代理方法
1.滑动代理方法相关
2.缩放代理方法相关
3.部分代理方法简明示例- UIScrollView处理触摸事件原理
- 常见需求示例 & 原理解析
1.导航栏半透明效果
2.控件导航悬停
3.下拉头部图片放大
4.正反无限轮播(3张)重点- UIScrollView底层实现
- 正反无限轮播(2张)
- UIScrollView.h属性和方法
- 期待 & 后续
UIScrollView概念
我还是喜欢先看官方的说明:

上图简明释义:
可以展示比设备屏幕更大区域的内容,我们可以通过手指滑动来查看内容视图(content view)的每一部分内容,也可以通过手指捏合来对内容视图进行缩放操作。
UIScrollView 是一个非常重要的控件,UITableView、UICollectionView和UITextView等常用控件全部继承自UIScrollView,而UIWebView控件内部也是基于UIScrollView实现的。而UIScrollView继承自UIView,至于它可以滚动的原因我下面会有原理说明。
UIScrollView基本使用(滚动)
UIScrollView的使用很简单,基本使用方式如下 3点:
|
|
- 说明:如果想让
UIScrollView进行滚动,必须设置可以滚动的范围
UIScrollView属性与方法
属性 & 方法:
|
|
使用格式 & 说明:
|
|
简明注解:
对于 UIScrollView 最重要的属性 contentSize、 contentOffset、 contentInset,要有正确的认知。
这个图很能说明,这三个属性的区别:
解答上面问题:苹果设计的代理属性为什么是weak?

上图注解:
原因:防止造成循环引用
说明:
rootViewController指针指向控制器对象(每个控制器都有个View被 强引用)–>UIView对象(强引用 内部 属性subViews)–> 子控件数组对象(强引用 假设scr对象在第0位)–>UIScrollView对象将ViewController设置为自己的代理(delegate),所以的用 弱引用 weak。假设没有指针指向这个控制器,而
delegate(weak弱引用) 没有强指针引用,控制器就会释放。
UIScrollView代理方法
滑动代理方法相关
|
|
缩放代理方法相关
|
|
部分代理方法简明示例
|
|
UIScrollView处理触摸事件原理
当用户在UIScrollView的一个子视图上按下时,UIScrollView并不知道用户是想要滑动内容视图还是点击对应子视图,所以在按下的一瞬间,事件UIEvent从UIApplication传递到UIScrollView后,其会先将该事件拦截而不会立即传递给对应的子视图,同时开始一个150ms的倒计时,并监听用户接下来的行为
当倒计时结束前,如果用户的手指发生了移动,则直接滚动内容视图,不会将该事件传递给对应的子视图;
当倒计时结束时,如果用户的手指位置没有改变,则调用自身的
-touchesShouldBegin:withEvent:inContentView:方法询问是否将事件传递给对应的子视图(如果返回NO,则该事件不会传递给对应的子视图,如果返回YES,则该事件会传递给对应的子视图,默认为YES)。当事件被传递给子视图后,如果手指位置又发生了移动,则调用自身的
-touchesShouldCancelInContentView:方法询问是否取消已经传递给子视图的事件。
常见需求示例 & 原理解析
导航栏半透明效果
原理解析:
默认情况下,在有
UINavigationBar存在时,系统为了防止UIScrollView被遮挡,其contentInset和scrollIndicatorInsets属性都会被设置为UIEdgeInsetsMake(64, 0, 0, 0);在有UITabBar存在时,系统为了防止UIScrollView被遮挡,其contentInset和scrollIndicatorInsets属性都会被设置为UIEdgeInsetsMake(0, 0, 49, 0)因此,为了使用此种半透明效果,可以直接将
UIScrollView的frame设置为整个屏幕的大小。注1: 系统只在
UIScrollView是控制器视图的第0个子视图时才会自动修改contentInset和scrollIndicatorInsets属性。注2: 如果不想让系统自动修改
contentInset和scrollIndicatorInsets属性,可以设置self.automaticallyAdjustsScrollViewInsets = NO;
控件导航悬停
原理解析:
- 通过
-scrollViewDidScroll:代理方法跟踪contentOffset的的变化,当不满足悬停条件时,待悬停控件属于UIScrollView的子视图,当满足悬停条件时,待悬停控件属于UIScrollView的父视图的子视图。
|
|
下拉头部图片放大
原理解析:
- 通过
-scrollViewDidScroll:代理方法跟踪contentOffset的的变化,根据contentOffset动态设置图片的缩放比例。
|
|
正反无限轮播(3张)
原理解析:

- 手动滚动:只创建三张图片: leftImageView、centerImageView、rightImageView,定义中间显示页码为 centerPage ,设置初始
self.centerPage = 0;,而左右图片页码都以 centerPage 表示,通过scrollViewDidEndDecelerating:方法判断contentOffsest.x和scrollView.frame.size.width比较,使改变self.centerPage的值,然后对应页码滚动取数组中的图片,始终显示中间一张。
- 定时器滚动: 将定时器添加到
Runloop的NSRunLoopCommonModes下,触发方法中设置setContentOffset: animated:YES方法动画结束时调用scrollViewDidEndScrollingAnimation:(仅当animated设置为YES时才调用),这个方法下self.centerPage++;。OK了
监听图片点击
当图片被点击的时候,我们往往需要执行某些操作,因此需要监听图片的点击,思路如下:
- 1.定义一个
block属性暴露给外界void(^LNBlock)(NSInteger index),(不会block的可以用代理,或者看这里 Block模式详解)。 - 2.设置
centerImageView的userInteractionEnabled为YES。 - 3.给
scrollView添加一个点击的手势 - 4.在手势方法里调用
block,并传入图片索引
核心代码
|
|
UIScrollView底层实现
|
|
总结:
UIScrollView 继承自UIView,内部加了手势,之所以可以滑动,是改变了bounds,若手指向上滑动,y++,内容就会向上滑动。这样我们也可以用 给UIView 添加个 Pan手势 实现滚动效果。
正反无限轮播(2张)
大致原理:
最底层是一个UIView,上面有一个UIScrollView以及UIPageControl,scrollView上有两个UIImageView,imageView宽高 = scrollview宽高 = view宽高;
假设轮播控件的宽度为x高度为y,我们设置scrollview的contentSize.width为3x,并让scrollview的水平偏移量为x,既显示最中间内容。
具体细节请移步这里阅读:
轮播两个ImageView实现 http://www.jianshu.com/p/ef03ec7f23b2
正反无限轮播 效果图
期待
- 如果在阅读过程中遇到 error || new ideas,希望你能 messages 我,我会及时改正谢谢。
- 点击右上角的 喜欢 和 订阅Rss 按钮,可以收藏本仓库,并在 Demo 更新时收到邮件通知。