OCiOS动效设计:UITableView 实现滚动视差效果
2016-05-06 22:26
811 查看
前言
最近在使用‘悦跑圈’这个App,其‘跑鞋展厅’功能的滚动视差效果深深地吸引了我,在网上搜罗了大量的资料,如下,我将仿照该效果简单介绍实现方法。效果演示
细节实现
OffsetImageCell.m- (void)cellOffset { // 1、获取cell在屏幕中的rect CGRect centerToWindow = [self convertRect:self.bounds toView:self.window]; // 2、获取cell中心点y轴坐标 CGFloat centerY = CGRectGetMidY(centerToWindow); // 3、获取cell父视图的中心点 CGPoint windowCenter = self.superview.center; // 4、获取距离差 CGFloat cellOffsetY = centerY - windowCenter.y; // 5、距离差 / 2倍父视图高度 CGFloat offsetDig = cellOffsetY / self.superview.frame.size.height * 2; CGFloat offset = -offsetDig * (kScreenHeight * 0.5 - kCellHeight) / 2; CGAffineTransform transY = CGAffineTransformMakeTranslation(0, offset); self.pictureView.transform = transY; }
viewController.m
- (void)tableView:(UITableView *)tableView willDisplayCell:(OffsetImageCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { // 1、cell 出现时的效果 // 防止加载时滑动卡顿 CATransform3D rotation;//3D旋转 rotation = CATransform3DMakeTranslation(0 ,50 ,20); // rotation = CATransform3DMakeRotation( M_PI_4 , 0.0, 0.7, 0.4); // 逆时针旋转 rotation = CATransform3DScale(rotation, 0.9, .9, 1); rotation.m34 = 1.0/ -600; cell.layer.shadowColor = [[UIColor blackColor]CGColor]; cell.layer.shadowOffset = CGSizeMake(10, 10); cell.alpha = 0; cell.layer.transform = rotation; [UIView beginAnimations:@"rotation" context:NULL]; //旋转时间 [UIView setAnimationDuration:0.6]; cell.layer.transform = CATransform3DIdentity; cell.alpha = 1; cell.layer.shadowOffset = CGSizeMake(0, 0); [UIView commitAnimations]; // 2、滚动视差效果实现 [cell cellOffset]; } - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(OffsetImageCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { [cell cancelAnimation]; }
完整实现
Tips1、图片素材及描述信息可自行设置;
2、修改状态栏样式可参考这篇文章;
steps 1:自定义 cell
#import <UIKit/UIKit.h> @interface OffsetImageCell : UITableViewCell @property (nonatomic, strong) UIImageView *pictureView; /**< 图片视图 */ @property (nonatomic, strong) UILabel *titleLabel; /**< 标题文本 */ - (void)cellOffset; /**< 偏移单元格 */ - (void)cancelAnimation; /**< 取消动画 */ @end
#import "OffsetImageCell.h" // 屏幕高度 #define kScreenHeight [UIScreen mainScreen].bounds.size.height // 屏幕宽度 #define kScreenWidth [UIScreen mainScreen].bounds.size.width // cell高度 #define kCellHeight 250 @implementation OffsetImageCell #pragma mark - Initialize - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { // 1、配置cell属性 self.selectionStyle = UITableViewCellSelectionStyleNone; self.clipsToBounds = YES; // 2、视图加载 [self.contentView addSubview:self.pictureView]; [self.contentView addSubview:self.titleLabel]; // 3、自定义分割线 UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, kCellHeight - 1, kScreenWidth, 1)]; line.backgroundColor = [UIColor lightGrayColor]; [self.contentView addSubview:line]; } return self; } #pragma mark - Handle offset - (void)cancelAnimation { [self.pictureView.layer removeAllAnimations]; } - (void)cellOffset { // 1、获取cell在屏幕中的rect CGRect centerToWindow = [self convertRect:self.bounds toView:self.window]; // 2、获取cell中心点y轴坐标 CGFloat centerY = CGRectGetMidY(centerToWindow); // 3、获取cell父视图的中心点 CGPoint windowCenter = self.superview.center; // 4、获取距离差 CGFloat cellOffsetY = centerY - windowCenter.y; // 5、距离差 / 2倍父视图高度 CGFloat offsetDig = cellOffsetY / self.superview.frame.size.height * 2; // 6、计算偏移 kScreenHeight * 0.5 为图片视图的高度 CGFloat offset = -offsetDig * (kScreenHeight * 0.5 - kCellHeight) / 2; CGAffineTransform transY = CGAffineTransformMakeTranslation(0, offset); self.pictureView.transform = transY; } #pragma mark - Getters - (UIImageView *)pictureView { if (!_pictureView) { _pictureView = [[UIImageView alloc]initWithFrame:CGRectMake(0, - (kScreenHeight * 0.5 - kCellHeight) / 2, kScreenWidth, kScreenHeight * 0.5)]; } return _pictureView; } - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [[UILabel alloc] init]; _titleLabel.bounds = CGRectMake(0, 0, kScreenWidth, 45); _titleLabel.center = CGPointMake(kScreenWidth * 0.5, kCellHeight * 0.5); _titleLabel.font = [UIFont boldSystemFontOfSize:25]; _titleLabel.textColor = [UIColor whiteColor]; _titleLabel.textAlignment = NSTextAlignmentCenter; } return _titleLabel; } @end
steps 2:ViewController 代码实现
#import "ViewController.h" #import "OffsetImageCell.h" @interface ViewController () <UITableViewDataSource, UITableViewDelegate> { NSArray *_dataSource; /**< 数据源 */ } @property (nonatomic, strong) UITableView *tableView; /**< 表格视图 */ - (void)initializeDataSource; /**< 初始化数据源 */ - (void)initializeUserInterface; /**< 初始化用户界面 */ @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self initializeDataSource]; [self initializeUserInterface]; } #pragma mark - Initialize - (void)initializeDataSource { // 初始化数据源; // 图片素材可自己准备; _dataSource = @[@{@"imgName":@"0.jpg", @"description":@"柯尼塞格"}, @{@"imgName":@"1.jpg", @"description":@"布加迪威龙"}, @{@"imgName":@"2.jpg", @"description":@"阿斯顿马丁"}, @{@"imgName":@"3.jpg", @"description":@"法拉利"}, @{@"imgName":@"4.jpg", @"description":@"迈凯伦"}, @{@"imgName":@"5.jpg", @"description":@"兰博基尼"}, @{@"imgName":@"6.jpg", @"description":@"奔驰"}, @{@"imgName":@"7.jpg", @"description":@"奥迪"}, @{@"imgName":@"8.jpg", @"description":@"劳斯莱斯"}, @{@"imgName":@"9.jpg", @"description":@"玛莎拉蒂"}]; } - (void)initializeUserInterface { // 1、关闭系统自动偏移 self.automaticallyAdjustsScrollViewInsets = NO; // 2、加载表格视图 [self.view addSubview:self.tableView]; } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _dataSource.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { OffsetImageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"123" forIndexPath:indexPath]; cell.pictureView.image = [UIImage imageNamed:_dataSource[indexPath.row][@"imgName"]]; cell.titleLabel.text = _dataSource[indexPath.row][@"description"]; return cell; } #pragma mark - UITableViewDelegate // 将要显示cell时调用 - (void)tableView:(UITableView *)tableView willDisplayCell:(OffsetImageCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { // 1、cell 出现时的效果 // 防止加载时滑动卡顿 CATransform3D rotation;//3D旋转 rotation = CATransform3DMakeTranslation(0 ,50 ,20); // rotation = CATransform3DMakeRotation( M_PI_4 , 0.0, 0.7, 0.4); // 逆时针旋转 rotation = CATransform3DScale(rotation, 0.9, .9, 1); rotation.m34 = 1.0/ -600; cell.layer.shadowColor = [[UIColor blackColor]CGColor]; cell.layer.shadowOffset = CGSizeMake(10, 10); cell.alpha = 0; cell.layer.transform = rotation; [UIView beginAnimations:@"rotation" context:NULL]; //旋转时间 [UIView setAnimationDuration:0.6]; cell.layer.transform = CATransform3DIdentity; cell.alpha = 1; cell.layer.shadowOffset = CGSizeMake(0, 0); [UIView commitAnimations]; // 2、滚动视差效果实现 [cell cellOffset]; } // cell显示完时调用 - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(OffsetImageCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { [cell cancelAnimation]; } // 设置cell高度 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 250; } #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // 获取可以见到的 cell,让图片在cell坐标改变的时候偏移 NSArray<OffsetImageCell *> *array = [self.tableView visibleCells]; [array enumerateObjectsUsingBlock:^(OffsetImageCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj cellOffset]; }]; } #pragma mark - Getters - (UITableView *)tableView { if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, CGRectGetHeight(self.view.bounds)) style:UITableViewStylePlain]; _tableView.dataSource = self; _tableView.delegate = self; [_tableView registerClass:[OffsetImageCell class] forCellReuseIdentifier:@"123"]; } return _tableView; } @end
源码地址
http://download.csdn.net/download/hierarch_lee/9512518相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用中UISearchDisplayController搜索效果的用法
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- iOS推送的那些事
- IOS 改变键盘颜色代码