之前在項目中用過一個視差效果蜗帜,其實實現(xiàn)并不是很難来惧,我們先看一下效果 </br>
大概說一下思路:</br>
每個cell中有一個UIImageView洽蛀,在tableview向上滑動的時候耙蔑,cell中的imageview相對cell向下移動结序,形成一個視差效果。也就是說纵潦,除了屏幕最上端的cell中的imageview的y為0以外,下面的cell中的imageview的Y值均為負(fù)值垃环。
接下來就依照已知量來計算每個imageView的y值邀层,并且在tableview滾動的時候?qū)崟r更改imageView的Y值。
已知量:</br>
- tableView的高度(tableViewHeight)</br>
- tableView的偏移量</br>
- cell的高度</br>
- imageView的高度</br>
- cell的Y值
- cell相主屏幕的偏移量(cellOffset) -> cellY值 - tableView的偏移量</br>
求imageView的偏移量(imageViewOffset)遂庄。如下圖所示寥院。
思路:
當(dāng)cell的偏移量變?yōu)?的時候,imageViewY的值也由負(fù)值變?yōu)?涛目。</br>
imageViewY的最大值為 imageViewHeight - cellHeight秸谢。</br>
因此可得如下公式:</br>
cellOffset/tableViewHeight = imageViewOffset/(imageViewHeight - cellHeight);</br>
imageViewOffset = cellOffset/tableViewHeight * (imageViewHeight - cellHeight);
好了,啰嗦完了霹肝,上代碼:
新建一個工程估蹄,在工程中自定義一個cell,cell中放一個UIImageView控件,讓UIImageView控件的高度大于Cell的高度。我這里設(shè)置為300甜无;cell的高度設(shè)為200热凹;
并且增加兩個方法:
// 獲取圖片最大偏移量
- (CGFloat)imageOverflowHeight;
// 重新設(shè)置圖片偏移量
- (void)setImageOffset:(CGPoint)imageOffset族檬;
自定義cell.m中的代碼如下:
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_mainImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width , 300)];
_mainImageView.contentMode = UIViewContentModeScaleAspectFill;
[self.contentView addSubview:_mainImageView];
_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 80, [UIScreen mainScreen].bounds.size.width, 40)];
_titleLabel.backgroundColor = [UIColor colorWithRed:0.94 green:0.94 blue:0.94 alpha:0.50];
_titleLabel.text = @"這是圖片上的文字";
_titleLabel.textAlignment = 1;
[self.contentView addSubview:_titleLabel];
}
return self;
}
/**
* 返回圖片大于imageView的高度
*
* @return 圖片大于imageView的高度
*/
- (CGFloat)imageOverflowHeight
{
// 減200 是因為cell的高度設(shè)為200,所以直接寫固定值了
return _mainImageView.frame.size.height - 200;
}
/**
* 設(shè)置imageView偏移量
*
* @param imageOffset 偏移量
*/
- (void)setImageOffset:(CGPoint)imageOffset
{
CGRect frame = _mainImageView.frame;
frame.origin = imageOffset;
_mainImageView.frame = frame;
}
在VC中添加一個tableview控件,工程中拖入一些圖片備用系枪。VC.m的代碼如下:
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) NSMutableArray *sourceArr;
@property (nonatomic, strong) UITableView *mainTable;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_sourceArr = [NSMutableArray array];
for (NSInteger i = 1; i <= 44; i++) {
NSString *imageName = [NSString stringWithFormat:@"img%ld.jpg", i];
[_sourceArr addObject:imageName];
}
_mainTable = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
_mainTable.delegate = self;
_mainTable.dataSource = self;
_mainTable.separatorStyle = UITableViewCellSeparatorStyleNone;
[_mainTable registerClass:[LTParallaxCell class] forCellReuseIdentifier:@"cell"];
[self.view addSubview:_mainTable];
}
/**
* 設(shè)置imageView的偏移量
*
* @param cell
*/
- (void)updateImageViewCellOffset:(LTParallaxCell *)cell
{
// 獲取cell的偏移量
CGFloat cellOffset = cell.frame.origin.y - self.mainTable.contentOffset.y;
// 獲取imageView的最大偏移量
CGFloat imgMaxHeight = [cell imageOverflowHeight];
// 計算imageView新的偏移量
CGFloat offset = 0.0f - imgMaxHeight * cellOffset / self.mainTable.frame.size.height;
// 設(shè)置imageView新的偏移量
[cell setImageOffset:CGPointMake(0.0f, offset)];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_sourceArr count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LTParallaxCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.mainImageView.image = [UIImage imageNamed:[_sourceArr objectAtIndex:indexPath.row]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.clipsToBounds = YES;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 200;
}
#pragma mark - UIScrollViewdelegate methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
for (LTParallaxCell *cell in self.mainTable.visibleCells) {
[self updateImageViewCellOffset:cell];
}
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self updateImageViewCellOffset:(LTParallaxCell *)cell];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
至此,一個視差效果就完成了磕谅,如果有什么錯誤的地方歡迎大家指正私爷。</br>
本人個人博客地址:http://www.lrymlt.cn/blog/