多种方法使tableView的Header下拉放大

前言

看了峥吖同学的这篇文章【一行代码快速集成tableView头部缩放视图】之后 。想着自己用其他的方法来实现这一效果,于是乎想到

1
CGAffineTransformMakeScale

这一方法。

效果图

下拉放大.gif

开始实现

在自己写的过程中发现了一些问题, 直接把

1
self.tableView.tableHeaderView = self.imageView

之后并不能达到想要的效果。整张图片frame都随着tableview的拖动而改变。并不是像是固定在那里。tableview的顶部会出现大部分空白。然后我仔细看了一遍源码。发现做法是

1
[self.tableView insertSubview:imageView atIndex:0];

接着把一个透明view填充到tableview的header view中。

1
2
3
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];    
headerView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = headerView;

找到这一技巧之后。自己写了一个稍微简单的demo。

1
2
3
4
5
6
7
8
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"header"]];
imageView.frame = CGRectMake(0, 0, self.view.frame.size.width, imageViewH);
[self.tableView insertSubview:imageView atIndex:0];
self.imageView = imageView;

UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, imageViewH)];
headerView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = headerView;

1
- (void)scrollViewDidScroll:(UIScrollView *)scrollView

方法中这么写:

1
2
3
4
5
6
CGFloat offsetY = scrollView.contentOffset.y;
if (offsetY < 0) {
self.imageView.frame = CGRectMake(offsetY, offsetY, scrollView.bounds.size.width - offsetY * 2, imageViewH - offsetY);
} else {
self.imageView.frame = CGRectMake(0, 0, scrollView.bounds.size.width, imageViewH);
}

原理一模一样,拿到scrollview的偏移量计算下拉imageview的frame,使其imageview的宽高增大。上拉的时候恢复原来的frame。

另一种方法

还是在

1
- (void)scrollViewDidScroll:(UIScrollView *)scrollView

方法中拿到scrollview的偏移量计算缩放系数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CGFloat offsetY = scrollView.contentOffset.y + scrollView.contentInset.top;
CGFloat scale = 1.0;
if (offsetY < 0) {
//向下拉
scale = MIN(2.5, 1 - offsetY / imageViewH);
self.imageView.transform = CGAffineTransformMakeScale(scale, scale);
CGRect frame = self.imageView.frame;
frame.origin.y = offsetY;
self.imageView.frame = frame;
}else if(offsetY > 0)
{
//向上拉
CGRect frame = self.imageView.frame;
frame.origin.y = -offsetY/imageViewH;
self.imageView.frame = frame;
}

再向上拉的过程中要保证imageview不会进行缩放,只是改变下imageview的y轴的值。

最后

感谢峥吖同学提供的思路。demo地址:戳我