首先要明确的是,scrollview 其实和普通的 view 并没有多大的差别,只不过给它加上了一些手势和约定。

我们知道,要让一个 scrollview 能够滚动的方法是设置它的 contentSize 的宽或者高或者同时比自己的 frame 大。

想一想为什么要这样做?

首先,scrollview 被苹果开发出来是为了通过滚动来显示比自己的 size 更多的内容,如果它的 contentSize 比自己都小,就没有滚动的必要了。

但实际上,scrollview 并没有滚动,当你在“拖动” scrollview 时,你其实是在改变 scrollview 的 bounds.origin。

那么什么是 bounds 呢? bounds 和 frame 又有什么关系呢?

bounds 是一个 view 自身的坐标系,它的作用是规定它自身的内容从什么位置开始绘制。 frame 是一个 view 相对于自己父视图的位置。它们是完全不相关联的。

你已经知道的是,当你“拖动” scrollview 时, scrollview 的代理会收到scrollViewDidScroll: 的消息,在里面打印 scrollview 的 contentOffset 的值,这个值会随着你的“拖动”不停的变化。这时候,尝试打印一下 scrollview 的 bounds.origin 的值,你会发现,这个值竟然和前面的值一样。contentOffset 只是为了更好的说明情况给 bounds.origin 换了个名字而已。

contentSize 只是抽象的概念,它规定的其实是 scrollview 的 bounds.origin 能够变化的范围。

理解到这里,像其他的 scrollview 的特性,例如 bounces 等,都可以得到解释。

scrollview 还增加了一个特性,contentInset,它用来 scrollview 增加额外的滚动范围,其实就是把 bounds.origin 的变化范围扩大了。当你给 scrollview 设置 contentInset 的时候,你会发现,它的 contentSize 并没有改变。

一般情况下,你并不会通过直接设置 contentSize 来达到你“滚动”的目的,因为当你想让 scrollview 的所有内容都能够通过“滚动”的方式显示时,你很难计算子视图整体的大小, 因为子视图在当时有可能还没决定自己的大小。所以通常来说,你会用 scrollview 的子类,例如 tableview 和 textview。他们会根据自己内容的大小自动的设置 scrollview 的 contentSize,以便包裹所有内容。当然他们有自己不同的使用场景。

同样,当我们试图实现类似的功能时,我们该怎么做呢?

这里我们会用到 Auto layout。只要 scrollview 的子视图确定了自己的大小,那么 scrollview 的 contentSize 就确定了,scrollable area 也就确定了。

这里的最佳实践是首先在 scrollview 上添加一个四周的 edge constraints 与 scrollview 间距为0的 content view,接下来,把你想要的子视图添加上去并且设置好相应的约束就可以了。

当我们实现上面的功能后,如果我们还想通过增加一些额外的滚动空间来实现例如防止键盘遮挡视图、下拉刷新或者上拉加载的功能时,我们就可以通过简单的设置 scroll view 的 contentInset 来实现,而不必从一开始就去关心 contentSize 的大小。

问题思考:scrollView 的代理有 scrollViewDidScrollToTop: 的方法来通知 scrollView 滑动到了顶部,想一想它的原理是什么?如何知道 scrollView 滑动到底部了呢?如果还要加上考虑 contentOffset 和 contentInset 呢?

scrollView滚动原理的更多相关文章

  1. View的滚动原理简单解析

    一直对View的滚动了解的不深,说明确了吧也能说出个所以然来,所以我就花了点时间做了一个小小的总结,言归正传,view的滑动分为下面三种: 1)View本身不滚动,指滚动View的内容,这也是View ...

  2. tableView和scrollView滚动起冲突

    tableView和scrollView滚动起冲突 tableView也是继承的scrollView,所以在滚动的时候也会触发scrollView的代理方法,在scrollViewDidScroll中 ...

  3. android ScrollView滚动距离和判断滚动停止状态

    今天很高兴,自己解决了判断ScrollView滚动停止的监听,现在分享给大家. 因为ScrollView没有像listView中的setOnScrollListener()监听,当然也就没有SCROL ...

  4. scrollView滚动(通过代码)

    平时的开发中可能会要求scrollview滚动,一般的方法时通过scrollview.scrollto(0,1000);来实现,但是注意这个方法是在scrollview停止动画之后才能执行的,因为如果 ...

  5. Android对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17761431),请尊重他人的辛勤劳动成果,谢谢! 我之前写 ...

  6. [Unity]Unity开发NGUI代码实现ScrollView(滚动视图)

    Unity开发NGUI代码实现ScrollView(滚动视图) 下载NGUI包 导入NGUI3.9.1版本package 链接: http://pan.baidu.com/s/1mgksPBU 密码: ...

  7. Android ScrollView嵌套ScrollView滚动的问题解决办法

    引用:http://mengsina.iteye.com/blog/1707464 http://fenglog.com/article.asp?id=449 Android ScrollView嵌套 ...

  8. javascript无缝滚动原理

    相比之下,无缝拼接能避免切换时出现空白,使用户体验更好! 无缝滚动原理: 制作一个双胞胎,内容跟主体内容一致,样式一致,如果横向排列则并排,当切换的时候,就可以弥补主体空白的地方,其他按普通循环操作即 ...

  9. Android 对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming),请尊重他人的辛勤劳动成果,谢谢! 随着移动互联网的快速发展,它已经和我们的生活息息相关了,在 ...

随机推荐

  1. Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序

    先看一道Java面试题: public class Baset { private String baseName = "base"; // 构造方法 public Baset() ...

  2. Usual tiny skills & solutions

    Ubuntu and Win10 - double OS 2016-02-21 Yesterday I helped my friend install Ubuntu (14.04 LTS) on h ...

  3. 使用SQLiteOpenHelper的onUpgrade实现数据库版本升级

    Andoird的SQLiteOpenHelper类中有一个onUpgrade方法.帮助文档中只是说当数据库升级时该方法被触发.经过实践,解决了我一连串的疑问: 1. 帮助文档里说的"数据库升 ...

  4. ubuntu 14.04安装pypcap

    直接sudo apt-get install python-pypcap即可 How to install python-pypcap on Ubuntu 12.04 (Precise Pangoli ...

  5. C++使用vector

    #include <iostream> #include <string> #include <vector> using namespace std; void ...

  6. [LeetCode] Inorder Successor in BST 二叉搜索树中的中序后继节点

    Given a binary search tree and a node in it, find the in-order successor of that node in the BST. No ...

  7. [LeetCode] Power of Two 判断2的次方数

    Given an integer, write a function to determine if it is a power of two. Hint: Could you solve it in ...

  8. [LeetCode] House Robber II 打家劫舍之二

    Note: This is an extension of House Robber. After robbing those houses on that street, the thief has ...

  9. 【原】Spark之机器学习(Python版)(二)——分类

    写这个系列是因为最近公司在搞技术分享,学习Spark,我的任务是讲PySpark的应用,因为我主要用Python,结合Spark,就讲PySpark了.然而我在学习的过程中发现,PySpark很鸡肋( ...

  10. textarea 中的 innerHTML 和 value

    <textarea></textarea> <input type="button" value="click" /> &l ...