您的位置:首页 > 产品设计 > UI/UE

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];
}


完整实现

Tips

1、图片素材及描述信息可自行设置;

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS cell-滚动视差