效果图:

UICollectionView能够实现你想要的任何布局,Vincent Ngo在raywenderlich中,用swift介绍了如何实现书本翻页布局,不得不佩服Vincent Ngo的想法,链接地址:http://www.raywenderlich.com/94565/how-to-create-an-ios-book-open-animation-part-1;

本文参考了这种思想,用OC编程实现了其中一部分效果,如上图所示;下面代码在每处都加上了详细解释,欢迎大家提供意见,

新建一个BookCell,继承自UIcollectionViewCell,在实现部分,重写applyLayoutAttributes方法,实现书本边缘圆角效果:

#import "BookCell.h"@implementation BookCell{BOOL isRightPage;
}//初始化
- (instancetype)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {//设置背景self.bgView = [[UIView alloc] initWithFrame:self.contentView.bounds];self.bgView.backgroundColor = [UIColor whiteColor];[self.contentView addSubview:self.bgView];//添加图片self.imageView = [[UIImageView alloc] initWithFrame:self.bgView.bounds];[self.bgView addSubview:self.imageView];//添加星座labelself.textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 40)];self.textLabel.center = CGPointMake(self.bgView.bounds.size.width / 2 + 20, self.bgView.bounds.size.height - 20);[self.bgView addSubview:self.textLabel];//开启反锯齿self.layer.allowsEdgeAntialiasing = YES;}return self;
}//默认自定义布局,布局圆角 和 中心线
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {[super applyLayoutAttributes:layoutAttributes];//判断cell的奇数偶数if (layoutAttributes.indexPath.item % 2 == 0) {//如果偶数,则中心线在左边,页面右边有圆角,左边没有圆角isRightPage = YES;self.layer.anchorPoint = CGPointMake(0, 0.5);} else {isRightPage = NO;self.layer.anchorPoint = CGPointMake(1, 0.5);}//圆角设置UIRectCorner corner = isRightPage ? UIRectCornerTopRight | UIRectCornerBottomRight : UIRectCornerTopLeft | UIRectCornerBottomLeft;UIBezierPath *bezier = [UIBezierPath bezierPathWithRoundedRect:self.bgView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(16, 16)];//CAShapeLayer: 通过给定的贝塞尔曲线UIBezierPath,在空间中作图CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];maskLayer.frame = self.bgView.bounds;maskLayer.path = bezier.CGPath;self.bgView.layer.mask = maskLayer;self.bgView.clipsToBounds = YES;
}
@end

新建一个 BookLayout 布局类,继承自 UICollectionViewLayout ,在这里我们将实现关键的3个必须实现的布局方法:

1. prepareLayout

2. collectionViewContentSize

3.  layoutAttributesForElementsInRect

关键思想,是在 layoutAttributesForItemAtIndexPath 方法中,实现空间布局,考虑到frame的变化,旋转角度和旋转比例的变化,以及cell的frame变化后,anchor点的重新设定等;

#import "BookLayout.h"@implementation BookLayout//定义cell的尺寸
static CGFloat pageWidth = 180;
static CGFloat pageHeight = 280;
static CGFloat numberOfPages = 0; //定义总的cell个数- (void)prepareLayout {[super prepareLayout];//滚动结束时,翻动快些self.collectionView.decelerationRate = UIScrollViewDecelerationRateFast;numberOfPages = [self.collectionView numberOfItemsInSection:0];self.collectionView.pagingEnabled = YES;//滚动视图整页翻动
}//布局实时更新
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {return YES;
}//内容滚动区域设置
- (CGSize)collectionViewContentSize {//每个视图上显示两页CGFloat width = numberOfPages / 2 - 1;return CGSizeMake(width * self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
}//每个cell的布局设置
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {//获取cell的布局UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];//设置frameCGRect frame;frame.origin.x = self.collectionView.bounds.size.width / 2 - pageWidth / 2 + self.collectionView.contentOffset.x;frame.origin.y = (self.collectionViewContentSize.height - pageHeight) / 2;frame.size.width = pageWidth;frame.size.height = pageHeight;layoutAttributes.frame = frame;//设置ratioCGFloat page = (indexPath.item - indexPath.item % 2) * 0.5; //结果 0,0,1,1,2,2 ...CGFloat ratio = - 0.5 + page - (self.collectionView.contentOffset.x / self.collectionView.bounds.size.width); //通过偏移量,获取比重//限制比重if (ratio > 0.5) {ratio = 0.5 + 0.1 * (ratio - 0.5);} else if (ratio < -0.5) {ratio = - 0.5 + 0.1 * (ratio + 0.5);}//if ((ratio > 0 && indexPath.item % 2 == 1) || (ratio < 0 && indexPath.item % 2 == 0)) {if (indexPath.row != 1) {return nil;}}//计算旋转角度angle,设定3D旋转CGFloat newRatio = MIN(MAX(ratio, -1), 1);//计算m34CATransform3D transform = CATransform3DIdentity;transform.m34 = 1.0 / - 2000;CGFloat angle = 0.0f;if (indexPath.item % 2 == 0) {//中心线在左边angle = (1 - newRatio) * (-M_PI_2);} else if (indexPath.item % 2 == 1) {//中心线在右边angle = (1 + newRatio) * (M_PI_2);}angle += (indexPath.row % 2) / 1000;transform = CATransform3DRotate(transform, angle, 0, 1, 0);layoutAttributes.transform3D = transform;if (indexPath.row == 0) {layoutAttributes.zIndex = NSIntegerMax;}return layoutAttributes;
}//所有cell布局数组
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {NSMutableArray *array = [NSMutableArray array];for (NSUInteger i = 0; i < numberOfPages; i++) {NSIndexPath *index = [NSIndexPath indexPathForItem:i inSection:0];UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:index];if (attributes != nil) {[array addObject:attributes];}}return array;
}
@end

当布局完成后,我们就大功告成了,在 UICollectionView 中,实现代理和数据源就OK了

#import "BookView.h"
#import "BookCell.h"
#import "BookLayout.h"
@implementation BookView
{NSMutableArray *_array;NSMutableArray *_arrayStr;
}static NSString *const reuseIdentifier = @"cell";
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout {self = [super initWithFrame:frame collectionViewLayout:layout];if (self) {self.backgroundColor = [UIColor clearColor];self.dataSource = self;self.delegate =self;[self registerClass:[BookCell class] forCellWithReuseIdentifier:reuseIdentifier];self.showsHorizontalScrollIndicator = NO;_array = (NSMutableArray *)@[@"",@"封面.jpg",@"白羊座1.jpg",@"金牛座2.jpg",@"双子座3.jpg",@"巨蟹座4.jpg",@"狮子座5.jpg",@"处女座6.jpg",@"天平座7.jpg",@"天蝎座8.jpg",@"射手座9.jpg",@"魔蝎座10.jpg",@"水瓶座11.jpg",@"双鱼座12.jpg",@"封底.jpg",@""];_arrayStr = (NSMutableArray *)@[@"",@"",@"白羊座",@"金牛座",@"双子座",@"巨蟹座",@"狮子座",@"处女座",@"天平座",@"天蝎座",@"射手座",@"魔蝎座",@"水瓶座",@"双鱼座",@"",@""];}return self;
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 16;
}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {BookCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];cell.imageView.image = [UIImage imageNamed:_array[indexPath.row]];cell.textLabel.text = [NSString stringWithFormat:@"%@", _arrayStr[indexPath.row]];cell.textLabel.font = [UIFont systemFontOfSize:12];cell.textLabel.textColor = [UIColor colorWithRed:148 / 255.0f green:0.0f blue:211 / 255.0f alpha:1.0f];return cell;
}
@end
#import "ViewController.h"
#import "BookView.h"
#import "BookLayout.h"
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];BookLayout *layout = [[BookLayout alloc] init];BookView *book = [[BookView alloc] initWithFrame:CGRectMake(10, 100, 300, 500) collectionViewLayout:layout];[self.view addSubview:book];
}@end

是不是感觉不可思议!

代码下载地址:

http://download.csdn.net/download/et295394330/9122319

UICollectionView实现书本翻页布局相关推荐

  1. BookBlock - 效果非常真实的书本翻页预览

    这个名为 BookBlock 的图片预览效果是一个书展示或网上书店的概念,已全屏打开3D页面导航网格的形式显示图书的详细信息.我们可以打开书预览的摘录,其中有一些细节的网格.对于图书预览,我们在使用 ...

  2. unity 制作书本 翻页效果

    unity 制作书籍翻页效果 unity C# 翻书效果 2D 真实翻页 不使用插件 自制 实现思路: 将书本分为两边,一边一个翻页实现: 下图为书本的右面,以OA为分界线,△OAB是下一面的如上图的 ...

  3. 手机html5翻页效果代码,jquery html5手机端翻书效果_手指滑动书本翻页效果代码

    特效描述:jquery html5手机端翻书 手指滑动 书本翻页效果.显现手机端翻书效果,支持手拖动翻页 代码结构 1. 引入JS 2. HTML代码 function loadApp() { // ...

  4. 用Cocos Creator 模拟书本翻页效果

    1.简介 本文主要探讨了如何使用CocosCreator来模拟书本翻页效果,分别介绍了通过使用贝塞尔曲线和verlet积分算法来模拟书页底边在翻页过程中的弯曲形变,最后通过自定义assembler传入 ...

  5. html5 3d翻页,HTML5 3D书本翻页动画

    这是一款十分炫酷的HTML5 3D书本翻页动画,效果相对比较简单,拖拽鼠标模拟用手翻页,更漂亮的是翻页过程中,呈现出逼真的3D立体效果.书本中的文字和图片也会3D展示,非常酷. HTML代码 Lore ...

  6. 使用transform制作书本翻页效果

    transform transform属于CSS属性 Transform属性应用于元素的2D或3D转换.这个属性允许你将元素旋转,缩放,移动,倾斜等. 在网页中需要制作一些有立体感的3d效果,比如书本 ...

  7. HTML5 3D书本翻页动画

    这是一款十分炫酷的HTML5 3D书本翻页动画,效果相对比较简单,拖拽鼠标模拟用手翻页,更漂亮的是翻页过程中,呈现出逼真的3D立体效果.书本中的文字和图片也会3D展示,非常酷. HTML代码 < ...

  8. 核心动画实现书本翻页效果加载动画

    经常看到一些很好的动画加载视图,闲来无事就写了一个书本翻页样式的动画加载视图,核心技术是CALayer+CoreAnimation.项目源码地址:https://github.com/China131 ...

  9. 用 Cocos Creator 模拟书本翻页效果

    本篇文章作者:乐府-贝塔 乐府-贝塔:乐府前端核心开发,从事游戏开发多年,从 Cocos2d-x 做到 Cocos Creator,擅长渲染技术的相关优化.多年的前端开发经验激发了对技术研究的深厚兴趣 ...

最新文章

  1. 软件工程第二次作业完整版
  2. Python爬虫基础面试题为2020年初大学生就业做准备(文末附教程)
  3. SpringBoot项目在Eclipse中实现打包发布
  4. Java:用POI读写Excel
  5. SpringBoot:application.properties基本的参数配置
  6. [译] 第十一天: AeroGear Push Server - 轻松推送提示信息
  7. linux命令vi作用,详解Linux常用命令的用法(二)――――文本编辑器命令vi/vim
  8. 【递归】n个数的全排列
  9. MySql Workbench表PK UN UQ B等字符的含义
  10. WebSphere 管理员界面 修改配置之后,没有反应的原因,需要按下[保存]link
  11. 百面机器学习—1.特征工程
  12. oracle open 101,解决oracle数据库ORA-65101 container database set up incorrectly
  13. 3D Max 2016安装教程
  14. Android动画分类与总结
  15. 用C++完成华氏温度换摄氏温度
  16. 求椭圆的切线方程------很有对称美
  17. bzGhost打造跨平台即时聊天软件之专栏介绍
  18. Jquery-留言板
  19. 部署keepalive+lvs多master节点高可用
  20. BeautifulSoup安装

热门文章

  1. python分割_Python文件合并与分割操作方法工具
  2. 天才拓荒者之冯诺依曼
  3. 2014美国大学计算机科学专业排名,2014年美国大学计算机科学专业排名.doc
  4. Redis总结二 - 测试案例
  5. 利用iText.jar操作pdf文档
  6. 华为OD机试107-跳格子游戏
  7. Minimum Number of Refueling Stops(C++最低加油次数)
  8. Scratch 2.0的构建与二次开发手册
  9. 网校搭建9:微信登录
  10. Go语言学习14-基本流程控制