`
tank2308635
  • 浏览: 191633 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Leaves -- iOS上一种图书翻页效果的实现

阅读更多

 

 

Leaves -- iOS上一种图书翻页效果的实现

Leaves是由Tow Brow开发的一个简单的图书翻页控件,它巧妙地结合了镜像层、阴影层(用于半透明页)和渐变层(用于阴影)来实现图书的翻页效果。其翻页效果如下图所示:
特性
Leaves支持:
文本、图像、PDF等任何可被渲染到Graphics Context上的对象
通过拖动或点击来翻页
支持ipad和iphone大小的显示区域
Levels目前不支持以下特性
页面上的交互元素
轻扫动作
 
类和接口
Leaves中主要有三个类:LevelsView、LevelsViewController、LevelsCache:
LevelsCache:是一个辅助类,用于缓存显示页。它将显示的内容缓存为图片并保存。
LevelsView:是翻页视图,翻页的主要效果便在些实现。它定义了一系列的层对象,并通过操作这些层对象来实现翻页中各种效果。
LevelsViewController: LevelsView的控制器
类似于UITableView, LevelsView也有一个相关的数据源类(LeaveViewDataSource)与委托类(LeavesViewDelegate),它们分别有两个方法,如下所示
复制代码
@protocol LeavesViewDataSource <NSObject>
- (NSUInteger) numberOfPagesInLeavesView:(LeavesView*)leavesView;
- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx;
@end
@protocol LeavesViewDelegate <NSObject>
@optional
- (void) leavesView:(LeavesView *)leavesView willTurnToPageAtIndex:(NSUInteger)pageIndex;
- (void) leavesView:(LeavesView *)leavesView didTurnToPageAtIndex:(NSUInteger)pageIndex;
@end
 
层树结构
LevelsView中的层树结构如下图所示:
 
每一个层(Layer)都有其特殊的用途,或作为内容的显示层,或作为阴影层,具体说明如下:
topPage层:显示当前页的内容。
topPageOverlay层:在翻页过程中,该层覆盖于topPage层上,且颜色偏暗,从而使topPage未翻转的部分变暗,有阴影的感觉。
topPageShadow层:在翻页过程中,该层用于表达topPage被翻转部分所形成的阴影。
topPageReverse层:翻页过程中,topPage被翻转部分的反面的容器层。
topPageReverseImage层:反面的内容页。在竖屏下,用于显示topPage被翻转部分的内容,这些内容被映射到该层,给人感觉书是透明的。在横屏下,显示的是下一页的内容。
topPageReverseOverlay层:该层用于覆盖topPageReverse层,效果与topPageOverlay类似。
topPageReverseShading层:该层在topPageReverse层右侧形成一个阴影。
bottomPage层:topPage页的下一页所在的层。
bottomPageShadow层:该层为在翻页过程中在 bottomPage左侧形成的一个阴影层。
leftPage层:该层为横屏模式下左侧页所在的层。
leftPageOverlay层:该层覆盖于为 leftPage层,效果与topPageOverlay类似。
由上可以看出,层树中的层主要分为三类:
内容显示层:topPage、topPageReverseImage、bottomPage、leftPage
阴影层:topPageShadow、topPageReverseShading、bottomPageShadow
覆盖层:topPageOverlay、topPageReverseOverlay、leftPageOverlay

图片缓存
Tow Brow在处理不同的内容(文本、图像、PDF)时显示时,所采取的方法是一样的。他将内容缓存为图像,并显示在屏幕上。基本方法是将内容写进CGContextRef中,然后根据CGContextRef中的信息创建图像,具体方法如下:
复制代码
-(CGImageRef) imageForPageIndex:(NSUInteger)pageIndex {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, 
pageSize.width, 
pageSize.height, 
8, /* bits per component*/
pageSize.width * 4, /* bytes per row */
colorSpace, 
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextClipToRect(context, CGRectMake(0, 0, pageSize.width, pageSize.height));
[dataSource renderPageAtIndex:pageIndex inContext:context];
CGImageRef image = CGBitmapContextCreateImage(context);
CGContextRelease(context);
[UIImage imageWithCGImage:image];
CGImageRelease(image);
return image;
}

当然程序没有缓存所有页的内容,而是根据横竖屏的不同缓存适当数量的内容。每次翻页时会重新整理缓存中的内容。
翻页动画实现
在Leaves中,翻页的基本原理其实很简单:翻页过程中,根据手指的划动来不断的调整层树结构中每个层的frame,翻页结束后,重新调整内容显示层所显示的内容。
为此,LevelsView中设置了一个leafEdge变量,该变量是手指在屏幕上划动时Touch Point在屏幕x轴上的百分比位置,这个操作在touchesMoved:withEvent中完成:
复制代码
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
......
UITouch *touch = [event.allTouches anyObject];
CGPoint touchPoint = [touch locationInView:self];
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:0.07]
forKey:kCATransactionAnimationDuration];
self.leafEdge = touchPoint.x / self.bounds.size.width;
[CATransaction commit];
}

而在leafEdge的set方法中,我们根据leafEdge的值来重新设定各个Layer的frame属性
复制代码
- (void) setLayerFrames {
CGRect rightPageBoundsRect = self.layer.bounds;
CGRect leftHalf, rightHalf;
CGRectDivide(rightPageBoundsRect, &leftHalf, &rightHalf, CGRectGetWidth(rightPageBoundsRect) / 2.0f, CGRectMinXEdge);
if (self.mode == LeavesViewModeFacingPages) {
rightPageBoundsRect = rightHalf;
}
topPage.frame = CGRectMake(rightPageBoundsRect.origin.x, 
rightPageBoundsRect.origin.y, 
leafEdge * rightPageBoundsRect.size.width, 
rightPageBoundsRect.size.height);
topPageReverse.frame = CGRectMake(rightPageBoundsRect.origin.x + (2*leafEdge-1) * rightPageBoundsRect.size.width, 
rightPageBoundsRect.origin.y, 
(1-leafEdge) * rightPageBoundsRect.size.width, 
rightPageBoundsRect.size.height);
......
}

最后便是当手指离开屏幕时,如何处理翻页结果(将当前页翻过去还是没有翻过去)。这个操作在 这个操作在touchesEnded:withEvent中完成
复制代码
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
......
UITouch *touch = [event.allTouches anyObject];
CGPoint touchPoint = [touch locationInView:self];
BOOL dragged = distance(touchPoint, touchBeganPoint) > [self dragThreshold];
[CATransaction begin];
float duration;
if ((dragged && self.leafEdge < 0.5) || (!dragged && [self touchedNextPage])) {
[self willTurnToPageAtIndex:currentPageIndex + numberOfVisiblePages];
self.leafEdge = 0;
duration = leafEdge;
......
}
else {
[self willTurnToPageAtIndex:currentPageIndex];
self.leafEdge = 1.0;
duration = 1 - leafEdge;
.......
}
[CATransaction setValue:[NSNumber numberWithFloat:duration]
forKey:kCATransactionAnimationDuration];
[CATransaction commit];
}

如果需要在翻页后执行某些操作(如在屏幕上显示当前页数等),则可以在继承自 LevelsViewController的控制器中实现leavesView:didTurnToPageAtIndex方法。
在此需要注意的就是 topPageReverseImage在竖屏时做了如下的变换
复制代码
topPageReverseImage.contentsGravity = kCAGravityRight;
topPageReverseImage.transform = CATransform3DMakeScale(-1, 1, 1);
从而使topPageReverseImage显示的内容让人感觉是透过纸张,看到topPage的内容。
横屏与竖屏
Leaves还有一个特点就是其支持横屏时,能同时看到两页的内容(该效果是由Ole Begemann改进的)。该改进最关键的地方就是增加了leftPage层,同时在横屏显示时将屏幕一分为二,在左侧显示leftPage。同进在翻页的过程中,topPageReverseImage显示的是topPage页下一页的内容。在翻转屏幕时,会根据方向重新调整内容的显示。

分享到:
评论

相关推荐

    iOS 显示双页的leaves翻页

    在iOS开发中,"leaves"通常指的是一个用于创建类似纸质书籍翻页效果的UI组件。这个组件模拟了真实的纸张翻动的效果,为用户提供了一种沉浸式的阅读体验。"iOS 显示双页的leaves翻页"是指将原本单页显示的leaves组件...

    IOS应用源码之brow-leaves-67b10ed.zip

    【标题】"IOS应用源码之brow-leaves-67b10ed.zip" 提供的是一款iOS应用的源代码,其中包含了开发者在构建该应用程序时所编写的全部代码和资源文件。这个项目的版本号可能是67b10ed,这通常是一个Git仓库中的特定提交...

    ios 卷边的翻页效果

    为了在iOS上实现这一效果,开发者通常会使用Core Animation框架,它是苹果提供的一种强大的2D和3D图形渲染引擎。 Core Animation允许开发者创建复杂的动画序列,包括关键帧动画和基于模型的动画。对于卷边翻页效果...

    翻页效果测试 leaves

    这种效果模拟了传统纸质书籍翻页的行为,为数字内容提供了一种更加直观和互动的用户体验。"LeavesTestIpad"这个文件名暗示这可能是一个针对iPad设备的翻页效果测试项目。 在iOS开发中,实现翻页效果通常涉及到以下...

    IOS应用源码——ole-leaves-34b078f.zip

    ole-leaves项目作为一个开源的应用程序,提供了深入理解iOS应用开发架构和实现细节的机会。通过对ole-leaves-34b078f.zip这个压缩包的解压和分析,我们可以从中提取出许多宝贵的iOS开发知识点。 首先,项目名称"ole...

    IOS应用源码之翻页效果.zip

    【标题】"IOS应用源码之翻页效果.zip"揭示了这个压缩包是关于iOS平台上实现翻页效果的源代码示例。翻页效果在移动应用中非常常见,尤其是在电子书阅读器、相册应用或者产品展示等场景,能够提供类似真实物体翻页的...

    IOS应用源码——老外的翻页效果──相当牛.zip

    标题中的“IOS应用源码——老外的翻页效果──相当牛.zip”表明这是一个关于iOS应用的源代码,特别强调了其包含一个外国人设计的非常出色的翻页效果。这个翻页效果可能是模仿真实书籍翻页的动画效果,为用户提供更...

    IOS应用源码——3D书本翻页效果.zip

    【标题】"IOS应用源码——3D书本翻页效果.zip" 提供的是一个iOS应用程序的源代码,其中实现了3D书本翻页的视觉特效。这种效果通常用于电子阅读器或者图书展示类的应用中,能带给用户更加生动真实的阅读体验。 在iOS...

    电子书leaves 2d翻页

    《电子书leaves 2d翻页》是一个专注于在iOS平台上实现二维翻页效果的源码项目。在当今数字化阅读盛行的时代,电子书已经成为我们获取知识的重要方式之一。而“Leaves”这个名字,通常寓意着自然、轻盈,很形象地对应...

    iPhone代码实例-翻页效果

    总的来说,实现iPhone上的翻页效果是一个涉及多方面技术的过程,它需要对iOS的动画框架、手势识别以及视图操作有深入的理解。通过分析和学习这样的代码实例,开发者不仅可以掌握具体的技术,还能培养解决问题和实现...

    翻页效果,iphone,ipad,源代码

    总的来说,这个项目提供了一个在iOS设备上实现翻页效果的源代码实例,适合iOS开发者研究和学习。通过分析和理解这些源代码,开发者可以了解到如何在自己的应用中实现类似的交互效果,提高用户体验。这可能涉及到...

    iOS翻书效果 Leaves.zip

    在iOS开发中,实现引人入胜的用户体验是至关重要的,而“翻书效果”是增强用户沉浸感的一种独特方式。这个项目“Leaves”恰好提供了这样的功能,它使用Objective-C编写,旨在模拟iBook应用中的逼真翻页动画。让我们...

    leaves-deploy:leaves-deploy 是一个非常轻量级的自动化静态部署工具

    leaves-deploy 是一个非常轻量级的自动化静态部署工具 安装 npm install -save-dev leaves-deploy 配置 const config = { host:'', // 开发服务器地址 必填 port:'22', // 端口 默认 22 username:'', // 登录...

    老外写的翻页效果 leaves

    老外写的翻页效果 leaves老外写的翻页效果 leaves

    Go-leaves是GBRT模型预测代码的纯Go实现库

    Go-leaves是一个专门为Go语言设计的机器学习库,专注于实现GBRT(Gradient Boosting Regression Trees)模型的预测功能。GBRT是一种广泛应用的强学习算法,它通过迭代地添加弱预测器(通常是决策树)来构建一个强...

    ios 电子书多个demo

    3. **图片翻页效果(Leaves)**:为了提供更真实的阅读体验,许多电子书应用会使用动画模拟纸质书的翻页效果。这通常涉及复杂的自定义视图动画,可能用到CATransition或CAKeyframeAnimation来实现动态的页面翻转效果...

    yolo算法-茶叶数据集数据集-5740张图像带标签-tea-leaves-dataset.zip

    yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 标签格式(也可转成voc格式):&lt;class&gt; &lt;x_center&gt; &lt;y_center&gt; ...

    吉他谱_Fallen Leaves - Billy Talent.pdf

    初级入门吉他谱 guitar tab

    classify-leaves.zip

    "classify-leaves.zip"是一个专门针对树叶分类的数据集,采用Python编程语言进行处理,为我们提供了实践深度学习技术,尤其是图片分类的绝佳机会。 该数据集的核心组成部分包括以下四个文件: 1. **train.csv**:...

    树叶分类竞赛数据集classify-leaves_kaggle

    kaggle网站深度学习竞赛资源:树叶分类竞赛数据集

Global site tag (gtag.js) - Google Analytics