前言

很多app的个人中心上部的headView都实现了弹簧拉伸的效果,即tableView的top并不随着下拉而滑动,而是紧紧的停在屏幕的最上方。

我们今天就分析一下这个效果的实现方式。


分析

关键代码

- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView]; self.headView.bounds = CGRectMake(0, 0, self.tableView.bounds.size.width, 200);
self.tableView.tableHeaderView = self.headView;
self.topImageView.frame = self.headView.bounds;
[self.headView addSubview:self.topImageView]; //在viewDidLoad方法中记录原始的y和height
self.originY = self.topImageView.y;
self.originHeight = self.topImageView.height;
} #pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat offy = scrollView.contentOffset.y;
if (offy < 0) {
self.topImageView.y = offy;
self.topImageView.height = self.originHeight - offy;
}else{
self.topImageView.y = self.originY;
self.topImageView.height = self.originHeight;
}
}

ok,到此你已经实现了headView的弹簧效果了!

多想一步,进一步优化

虽然上面已经实现了功能所需,但是这个效果的代码跟项目耦合在一起的,不能复用。每次实现这个效果,都要写一遍上面的代码。不能忍啊,我们进一步优化!

我们创建一个名为UIScrollView+SpringHeadView.h的UIScrollView的分类

UIScrollView+SpringHeadView类中的实现方法如下

//UIScrollView+SpringHeadView.h的内容
#import <UIKit/UIKit.h>
//headView 的高度
#define SpringHeadViewHeight 200 @interface UIScrollView (SpringHeadView)<UIScrollViewDelegate>
//在分类增加了属性,这个是利用runtime实现的
@property (nonatomic, weak) UIView *topView;
- (void)addSpringHeadView:(UIView *)view;
@end
//UIScrollView+SpringHeadView.m的内容
- (void)setTopView:(UIView *)topView{
[self willChangeValueForKey:@"SpringHeadView"];
objc_setAssociatedObject(self, &UIScrollViewSpringHeadView,
topView,
OBJC_ASSOCIATION_ASSIGN);
[self didChangeValueForKey:@"SpringHeadView"];
} - (UIView *)topView{
return objc_getAssociatedObject(self, &UIScrollViewSpringHeadView);
} - (void)addSpringHeadView:(UIView *)view{
self.contentInset = UIEdgeInsetsMake(view.bounds.size.height, 0, 0, 0);
[self addSubview:view];
view.frame = CGRectMake(0, -view.bounds.size.height, view.bounds.size.width, view.bounds.size.height);
self.topView = view;
//使用kvo监听scrollView的滚动
[self addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
} - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[self scrollViewDidScroll:self];
} - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat offy = scrollView.contentOffset.y; if (offy < 0) {
self.topView.frame = CGRectMake(0, offy, self.topView.bounds.size.width, -offy);
}
}

现在我们使用起来爽了,只要需要引入UIScrollView+SpringHeadView.h,一行代码就能实现弹簧的效果啦!

//引入分类
#import "UIScrollView+SpringHeadView.h" - (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView]; self.topImageView.frame = CGRectMake(0, 0, self.tableView.bounds.size.width, SpringHeadViewHeight);
//只需要一行代码,就能实现同样效果
[self.tableView addSpringHeadView:self.topImageView];
}

获取完整的代码点我

最新文章

  1. Open Data Structure Templates
  2. RBAC用户权限管理数据库设计
  3. HTML前端--各种小案例
  4. TextArea限制输入长度
  5. linux 多网卡 跃点数
  6. 剑指offer—第三章高质量代码(数值的整数次方)
  7. [LeetCode] 204. Count Primes 解题思路
  8. JAVASCRIPT——文字出现效果练习
  9. Let the Balloon Rise(map)
  10. codeforces 451E. Devu and Flowers 容斥原理+lucas
  11. 从RGB色转为灰度色算法
  12. Shortest path of the king
  13. 基于Jmeter的自动化测试实施方案设计
  14. P1462 通往奥格瑞玛的道路 (二分+最短路)
  15. 面向对象之组合VS继承:继承过时了?
  16. Azure CosmosDB (10) Azure Cosmos DB体系结构
  17. js定时器整理(执行一次、重复执行)
  18. STOMP Over WebSocket
  19. gentoo intel 安装桌面
  20. [原][JSBSim]基于qt代码实现:TCP|UDP与飞行模拟软件JSBSim的通信,现实模型飞行!

热门文章

  1. linux下建立无线wifi------简单实用!
  2. Shell编程之函数调用
  3. asp.net将本地Excel上传到服务器并把数据导入到数据库
  4. oc学习之路-----搞死指针之内存存储int类型
  5. nginx查看进程连接信息
  6. 新安装XAMPP,phpMyAdmin错误:#1045 - Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: NO)
  7. android79 Fragment生命周期
  8. android 69 SQLite数据库
  9. 使用tuple返回多个值
  10. JS家的排序算法