CAScrollLayer
CAScrollLayer
对于一个未转换的图层,它的bounds和它的frame是一样的,frame属性是由bounds属性自动计算而出的,所以更改任意一个值都会更新其他值。
但是如果你只想显示一个大图层里面的一小部分呢。比如说,你可能有一个很大的图片,你希望用户能够随意滑动,或者是一个数据或文本的长列表。在一个典型的iOS应用中,你可能会用到UITableView或是UIScrollView,但是对于独立的图层来说,什么会等价于刚刚提到的UITableView和UIScrollView呢?
在第二章中,我们探索了图层的contentsRect属性的用法,它的确是能够解决在图层中小地方显示大图片的解决方法。但是如果你的图层包含子图层那它就不是一个非常好的解决方案,因为,这样做的话每次你想『滑动』可视区域的时候,你就需要手工重新计算并更新所有的子图层位置。
这个时候就需要CAScrollLayer了。CAScrollLayer有一个-scrollToPoint:方法,它自动适应bounds的原点以便图层内容出现在滑动的地方。注意,这就是它做的所有事情。前面提到过,Core Animation并不处理用户输入,所以CAScrollLayer并不负责将触摸事件转换为滑动事件,既不渲染滚动条,也不实现任何iOS指定行为例如滑动反弹(当视图滑动超多了它的边界的将会反弹回正确的地方)。
让我们来用CAScrollLayer来常见一个基本的UIScrollView替代品。我们将会用CAScrollLayer作为视图的宿主图层,并创建一个自定义的UIView,然后用UIPanGestureRecognizer实现触摸事件响应。这段代码见清单6.10. 图6.11是运行效果:ScrollView显示了一个大于它的frame的UIImageView。
清单6.10 用CAScrollLayer实现滑动视图
#import "ScrollView.h"
#import @implementation ScrollView
+ (Class)layerClass
{
return [CAScrollLayer class];
} - (void)setUp
{
//enable clipping
self.layer.masksToBounds = YES; //attach pan gesture recognizer
UIPanGestureRecognizer *recognizer = nil;
recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self addGestureRecognizer:recognizer];
} - (id)initWithFrame:(CGRect)frame
{
//this is called when view is created in code
if ((self = [super initWithFrame:frame])) {
[self setUp];
}
return self;
} - (void)awakeFromNib {
//this is called when view is created from a nib
[self setUp];
} - (void)pan:(UIPanGestureRecognizer *)recognizer
{
//get the offset by subtracting the pan gesture
//translation from the current bounds origin
CGPoint offset = self.bounds.origin;
offset.x -= [recognizer translationInView:self].x;
offset.y -= [recognizer translationInView:self].y; //scroll the layer
[(CAScrollLayer *)self.layer scrollToPoint:offset]; //reset the pan gesture translation
[recognizer setTranslation:CGPointZero inView:self];
}
@end
图6.11 用UIScrollView创建一个凑合的滑动视图
不同于UIScrollView,我们定制的滑动视图类并没有实现任何形式的边界检查(bounds checking)。图层内容极有可能滑出视图的边界并无限滑下去。CAScrollLayer并没有等同于UIScrollView中contentSize的属性,所以当CAScrollLayer滑动的时候完全没有一个全局的可滑动区域的概念,也无法自适应它的边界原点至你指定的值。它之所以不能自适应边界大小是因为它不需要,内容完全可以超过边界。
那你一定会奇怪用CAScrollLayer的意义到底何在,因为你可以简单地用一个普通的CALayer然后手动适应边界原点啊。真相其实并不复杂,UIScrollView并没有用CAScrollLayer,事实上,就是简单的通过直接操作图层边界来实现滑动。
CAScrollLayer有一个潜在的有用特性。如果你查看CAScrollLayer的头文件,你就会注意到有一个扩展分类实现了一些方法和属性:
- (void)scrollPoint:(CGPoint)p;
- (void)scrollRectToVisible:(CGRect)r;
@property(readonly) CGRect visibleRect;
看到这些方法和属性名,你也许会以为这些方法给每个CALayer实例增加了滑动功能。但是事实上他们只是放置在CAScrollLayer中的图层的实用方法。scrollPoint:方法从图层树中查找并找到第一个可用的CAScrollLayer,然后滑动它使得指定点成为可视的。scrollRectToVisible:方法实现了同样的事情只不过是作用在一个矩形上的。visibleRect属性决定图层(如果存在的话)的哪部分是当前的可视区域。如果你自己实现这些方法就会相对容易明白一点,但是CAScrollLayer帮你省了这些麻烦,所以当涉及到实现图层滑动的时候就可以用上了。
CAScrollLayer的更多相关文章
- iOS之CAScrollLayer属性简介和使用
1.CAScrollLayer的简介 CAScrollLayer用于显示一个滑动图层的一部分,可以确定滑动方向和可视区域面积,限制不滑出区域外!相关属性如下:其中 /* Scroll the cont ...
- ios项目里扒出来的json文件
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...
- Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...
- IOS Core Animation Advanced Techniques的学习笔记(五)
第六章:Specialized Layers 类别 用途 CAEmitterLayer 用于实现基于Core Animation粒子发射系统.发射器层对象控制粒子的生成和起源 CAGradient ...
- iOS - 开发类库
开发类库 UI 项目名称 项目信息 1.MJRefresh 仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能.可以自定义上下拉刷新的文字说明. ...
- iOS及Mac开源项目和学习资料【超级全面】
UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...
- Core Animation编程指南
本文是<Core Animation Programming Guide>2013-01-28更新版本的译文.本文略去了原文中关于OS X平台上Core Animation相关内容.因为原 ...
- iOS:iOS开发非常全的三方库、插件等等
iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...
- CALayer的分析
转载地址: http://my.oschina.net/u/2340880/blog/536048 iOS开发CoreAnimation解读之二——对CALayer的分析 一.UIView中的CAL ...
随机推荐
- 【JSP】EL表达式语言
EL简介 EL语言原本是JSTL1.0中的技术(所以EL和JSTL配合如此亲密和默契也就是自然的了),但是从JSP2.0开始(JSTL1.1)就分离出来纳入了JSP的标准了.因此EL不需要任何jar包 ...
- 【AngularJs-模块篇-Form篇】
1.模块 <!doctype html> <html lang="en-US" ng-app="myApp"> <head> ...
- Android系统dimension单位详解
转载请注明出处,谢谢!http://www.cnblogs.com/coding-way/p/3457878.html Android设备种类多样,要想适配好各种屏幕,理解各种屏幕数据是必须的.首先先 ...
- 初次使用visual studio
之前一直听闻VS是世界上最强IDE,但是害怕他的体积庞大,一直不敢使用.我一直喜欢轻便简洁的东西,编译器也是一样,所以刚开始我使用的是C-FREE5,虽然界面略显粗糙,和低调奢华有内涵的VS比起来,真 ...
- 爬虫自动登陆GitHub
import requests from bs4 import BeautifulSoup r1 = requests.get( url='https://github.com/login' ) s1 ...
- js获取文件对象
- poj2528 Mayor's posters【线段树】
The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign h ...
- TOP100summit 2017:【案例分享】魅族持续交付平台建设实践
本篇文章内容来自第10期魅族开放日魅族运维架构师林钟洪的现场分享.编辑:Cynthia 一.自动化建设历程1.1 魅族互联网发展的时间线 2003-2008年被称之为“互联网1.0时代”.2003年, ...
- 要学习的UML图
这是人人都是产品经理里的一节内容,这是个简单的例子,我觉得重要就摘抄一下 UML是要好好学习的一门课程呀
- Python实现简单HTTP服务器(二)
实现简单web框架 一.框架(MyWeb.py) # coding:utf-8 import time # 设置静态文件根目录 HTML_ROOT_DIR = "./html" c ...