Leaves -- iOS上一种图书翻页效果的实现
2013-07-17 11:48
387 查看
Leaves是由Tow Brow开发的一个简单的图书翻页控件,它巧妙地结合了镜像层、阴影层(用于半透明页)和渐变层(用于阴影)来实现图书的翻页效果。
特性
Leaves支持:
文本、图像、PDF等任何可被渲染到Graphics Context上的对象
通过拖动或点击来翻页
支持ipad和iphone大小的显示区域
Levels目前不支持以下特性
页面上的交互元素
轻扫动作
类和接口
Leaves中主要有三个类:LevelsView、LevelsViewController、LevelsCache:
LevelsCache:是一个辅助类,用于缓存显示页。它将显示的内容缓存为图片并保存。
LevelsView:是翻页视图,翻页的主要效果便在些实现。它定义了一系列的层对象,并通过操作这些层对象来实现翻页中各种效果。
LevelsViewController: LevelsView的控制器类似于UITableView, LevelsView也有一个相关的数据源类(LeaveViewDataSource)与委托类(LeavesViewDelegate),它们分别有两个方法,如下所示
每一个层(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中的信息创建图像,具体方法如下:
当然程序没有缓存所有页的内容,而是根据横竖屏的不同缓存适当数量的内容。每次翻页时会重新整理缓存中的内容。
翻页动画实现
在Leaves中,翻页的基本原理其实很简单:翻页过程中,根据手指的划动来不断的调整层树结构中每个层的frame,翻页结束后,重新调整内容显示层所显示的内容。
为此,LevelsView中设置了一个leafEdge变量,该变量是手指在屏幕上划动时Touch Point在屏幕x轴上的百分比位置,这个操作在touchesMoved:withEvent中完成:
而在leafEdge的set方法中,我们根据leafEdge的值来重新设定各个Layer的frame属性
最后便是当手指离开屏幕时,如何处理翻页结果(将当前页翻过去还是没有翻过去)。这个操作在 这个操作在touchesEnded:withEvent中完成
如果需要在翻页后执行某些操作(如在屏幕上显示当前页数等),则可以在继承自 LevelsViewController的控制器中实现leavesView:didTurnToPageAtIndex方法。
在此需要注意的就是 topPageReverseImage在竖屏时做了如下的变换
从而使topPageReverseImage显示的内容让人感觉是透过纸张,看到topPage的内容。
横屏与竖屏
Leaves还有一个特点就是其支持横屏时,能同时看到两页的内容(该效果是由Ole Begemann改进的)。该改进最关键的地方就是增加了leftPage层,同时在横屏显示时将屏幕一分为二,在左侧显示leftPage。同进在翻页 的过程中,topPageReverseImage显示的是topPage页下一页的内容。在翻转屏幕时,会根据方向重新调整内容的显示。
参考资料:App Store-safe Page Curl animations
源码下载地址:https://github.com/brow/leaves
特性
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
每一个层(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; }-(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页下一页的内容。在翻转屏幕时,会根据方向重新调整内容的显示。
参考资料:App Store-safe Page Curl animations
源码下载地址:https://github.com/brow/leaves
相关文章推荐
- Leaves -- iOS上一种图书翻页效果的实现
- Leaves -- iOS上一种图书翻页效果的实现
- iOS上一种图书翻页效果的实现(Leaves)详解
- Leaves -- iOS上一种图书翻页效果的实现
- iOS上一种图书翻页效果的实现(Leaves)详解
- Leaves -- iOS上一种图书翻页效果的实现1
- Leaves -- iOS上一种图书翻页效果的实现2
- Leaves -- iOS上一种图书翻页效果的实现
- Leaves -- iOS上一种图书翻页效果的实现
- Leaves -- iOS上一种图书翻页效果的实现
- Leaves -- iOS上一种图书翻页效果的实现
- iOS上一种图书翻页效果的实现(Lea…
- iphone上一种图书翻页效果的实现-- Leaves
- IOS 上图书翻页效果的实现
- iOS动效-利用CATransform3D实现翻页动画效果
- iOS 类似淘宝商品详情查看翻页效果的实现
- IOS实现半翻页效果
- Android实现图书的翻页效果
- IOS类似翻页效果实现实例
- turn.js实现图书翻页效果