前言

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

获取完整的代码点我

一行代码实现headView弹簧拉伸效果的更多相关文章

  1. [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想)

    2018年01月03日阅读 2472   [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想) LYEmptyView 此框架是本人在5,6个月前,公司启动新项目的时候, ...

  2. android Titlebar一行代码实现沉浸式效果

    github地址 一个简单易用的导航栏TitleBar,可以轻松实现IOS导航栏的各种效果  整个代码全部集中在TitleBar.java中,所有控件都动态生成,动态布局.不需要引用任何资源文件,拷贝 ...

  3. Swift3 页面顶部实现拉伸效果代码

    //懒加载 //顶部需要拉伸自定义视图 lazy var headView:MyHeaderView = { //let hframe = CGRect(x: 0, y: 0, width: swid ...

  4. 一行代码轻松实现拖动效果[JQuery]

    写JS实现拖动需要一大堆不便维护的代码,实属麻烦,Google了大半天,发现了一个优秀的Jquery插件EasyDrag,只需要一行代码便可轻松在主流浏览器上 实现拖动效果.   $(document ...

  5. 翻遍互联网都找不到的解决方案,一行代码轻松实现 Gitbook 默认折叠左侧菜单效果

    Gitbook 是一款产品文档构建工具,也可以用于构建个人博客,默认情况下电脑端访问时左侧菜单是展开状态,可偏偏有人想要实现默认折叠效果,于是诞生了这篇文章! 善良的我选择帮助别人 可能是网上关于 G ...

  6. Android开发之去掉listview的点击效果,一行代码间接粗暴,解决你的问题。

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之去掉listview的点击效果,一行代码间接粗暴,解决你的问题. 当你在用list ...

  7. 自定义一个更好用的SwipeRefreshLayout(弹力拉伸效果详解)(转载)

    转自: 自定义一个更好用的SwipeRefreshLayout(弹力拉伸效果详解) 前言 熟悉SwipeRefreshLayout的同学一定知道,SwipeRefreshLayout是android里 ...

  8. 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10

    行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 2012-04-25 16:29:04| 分类: 学习 |字号 订阅 在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE ...

  9. 【原】iOS动态性(四):一行代码实现iOS序列化与反序列化(runtime)

    为取得更好的排版效果,本文同样发布在简书上,强烈建议跳转到[1]http://www.jianshu.com/p/fed1dcb1ac9f 一.变量声明 为便于下文讨论,提前创建父类Biology以及 ...

随机推荐

  1. C# Sending data using GET or POST ZZ

    In this short article, I'll show you how to send data to a website from a C# application using GET o ...

  2. devi into python 笔记(一)字典 列表的简单操作

    模块: python中模块是很重要的概念,在模块中加入 if __name__ == "__main__": pass 会使模块应用起来更加灵活,避免出错. =========== ...

  3. ARM学习笔记10——GNU ARM命令行工具

    一.编译器arm-linux-gcc 1.用arm-linux-gcc编译一个程序,一般它是要经过如下步骤的: 1.1.预处理阶段 编译器把上述代码中stdio.h编译进来,使用GCC的选项-E可以使 ...

  4. Minimum Window Substring &&& Longest Substring Without Repeating Characters 快慢指针,都不会退,用hashmap或者其他结构保证

    1 public class Solution { public static int lengthOfLongestSubstring(String s) { char[] arr = s.toCh ...

  5. 哈希(2) hash索引

    首先复习:       索引:快速查找的数据结构 1.可以读以下mysql中索引的使用方法,图文并茂.很好理解. http://www.it165.net/database/html/201310/4 ...

  6. Bzoj 3171: [Tjoi2013]循环格 费用流

    3171: [Tjoi2013]循环格 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 741  Solved: 463[Submit][Status][ ...

  7. Android TextView : “Do not concatenate text displayed with setText”

    参考:http://stackoverflow.com/questions/33164886/android-textview-do-not-concatenate-text-displayed-wi ...

  8. Spark RDD概念学习系列之rdd持久化、广播、累加器(十八)

    1.rdd持久化 2.广播 3.累加器 1.rdd持久化 通过spark-shell,可以快速的验证我们的想法和操作! 启动hdfs集群 spark@SparkSingleNode:/usr/loca ...

  9. CentOS搭建GIT服务器【二】-HTTP源码访问及smart http协议

    搭建完git之后,我们希望可以在线看见源码,以及使用http协议上传下载源码. 安装gitweb.httpd: yum install gitweb yum install httpd gitweb默 ...

  10. Altium Designer6打印PCB 设置

    1.File-->Page Setup     Printer Paper一栏是打印纸的设置,不再罗嗦.     主要是Scaling一栏:ScaleMode项选择:ScaledPrint    ...