先看效果:
分析思路,当我往下拉的时候图片定在navigationbar下面,图片拉伸,而且cell和图片间的间隙始终不变,可以考虑用headerView做,但我也可以在cell上加一张图片,图片为tableview的子控件,当满足向下拉的条件时改变图片的位置和大小。这里我们先用第二种方法做。
-_-|||开撸
先把主界面搭出来(tableview的设置就略了)
这里设置contentInset是为了不把cell挡住
//设置图片的内边距空出一个imageView的位置
self.tableView.contentInset = UIEdgeInsetsMake(imageHeight, 0, 0, 0);
CGSize screenSize = [UIScreen mainScreen].bounds.size;
//把图片设置到对应位置上
UIImageView *topImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, -imageHeight, screenSize.width, imageHeight)];
这样主界面就搭好了,开始处理下拉操作(代码链接在最后,可以先下载看看)
这里有个误区,一开始我想把y值写死,这样在往下拉的范围内就使图片顶部定在一个位置,但是这里的imageView是tableview的子控件,控件本身的位置就是死的,拖拽只是控制tableview的内容上下滚动,并不改变子控件的frame属性。
现在我的contentInset是的图片的高度,所以我图片的y值位置就应该是-imageHeight
当我向下移动50的时候也就是contentOffset.y改变了50,这样我中间给图片留的位置就为imageHeight+50,所以我需要把y值重新赋值,因为有导航条的原因,scrollerView.contentOffset.y会自动下移navigationBarHeight(64)的高度,我需要加上navigationBarHeight 才能算出scrollerView.contentOffset.y的真实距离,也就是变量y
此时图片的y值应该等于-(imageHeight+50),y的初始值是- imageHeight 当向下拉50后变为-(imageHeight+50)所以把变量y赋值给图片的y值就实现向下拉会停在navigationBar的底部,再改变高度就能实现拉伸效果
#pragma mark - 监听滚动(程序启动会调用2次,设置内边距会再调用一次)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
//因为有导航栏的关系,所以要获得移动的距离需要加上导航栏的高度
CGFloat y = scrollView.contentOffset.y + navigationBarHeight;
if (y < -imageHeight) {
CGRect frame = self.topImgView.frame;
//MARK: 核心代码
frame.origin.y = y;
frame.size.height = -y;
self.topImgView.frame = frame;
}
}
现在的效果图
现在大体上已经实现了,但是左右也要拉伸,这是要用到一个属性
// UIViewContentModeScaleAspectFill也会证图片比例不变,但是是填充整个ImageView的,可能只有部分图片显示出来。
//这里是为了让图片宽度随着高度的拉伸而拉伸
topImgView.contentMode = UIViewContentModeScaleAspectFill;
看一下效果
因为它是根据实际宽高比来填充的,所以图片多少会有点变大,如图:图片挡住了第0行cell的一部分,并且图片上方也不在顶住navigationbar了,并且如果有一天需求改了,我需要显示的图片高度为50,但是这个属性是根据图片的原始大小来的,所以改了也没用:如图
既然对图片有要求,那我们就处理一下再给它不就好咯,不管图片从哪来的我把它设置成我想要的大小
#pragma mark - 给图片设置尺寸
- (UIImage *)originImage:(UIImage *)image scaleToSize:(CGSize)size{
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage * scaleImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaleImage;
}
在设置图片之前通过调用该方法改变图片大小
//MARK: 把加载的图片设置需要的大小
UIImage *oldImage = [UIImage imageNamed:@"5"];
topImgView.image = [self originImage:oldImage scaleToSize:CGSizeMake(screenSize.width, imageHeight)];
大功告成!不过这个一般是个人中心界面所以我设了一个头像
UIImageView * iconView = [[UIImageView alloc]initWithFrame:CGRectMake(iconMargin, imageHeight - (iconMargin + iconH), iconW, iconH)];
iconView.layer.cornerRadius =8.0f;
iconView.image = [UIImage imageNamed:@"01"];
iconView.clipsToBounds = YES;
//自动布局,自适应顶部
iconView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
[self.topImgView addSubview:iconView];
self.iconView = iconView;
如果想在图片中加其他控件可以参照这个头像的设置
最终效果
另外一种就是用headerView做了(现在还没写完~~)点击这里,源码见github:github地址。