一行代码实现headView弹簧拉伸效果

前言
很多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弹簧拉伸效果的更多相关文章
- [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想)
2018年01月03日阅读 2472 [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想) LYEmptyView 此框架是本人在5,6个月前,公司启动新项目的时候, ...
- android Titlebar一行代码实现沉浸式效果
github地址 一个简单易用的导航栏TitleBar,可以轻松实现IOS导航栏的各种效果 整个代码全部集中在TitleBar.java中,所有控件都动态生成,动态布局.不需要引用任何资源文件,拷贝 ...
- Swift3 页面顶部实现拉伸效果代码
//懒加载 //顶部需要拉伸自定义视图 lazy var headView:MyHeaderView = { //let hframe = CGRect(x: 0, y: 0, width: swid ...
- 一行代码轻松实现拖动效果[JQuery]
写JS实现拖动需要一大堆不便维护的代码,实属麻烦,Google了大半天,发现了一个优秀的Jquery插件EasyDrag,只需要一行代码便可轻松在主流浏览器上 实现拖动效果. $(document ...
- 翻遍互联网都找不到的解决方案,一行代码轻松实现 Gitbook 默认折叠左侧菜单效果
Gitbook 是一款产品文档构建工具,也可以用于构建个人博客,默认情况下电脑端访问时左侧菜单是展开状态,可偏偏有人想要实现默认折叠效果,于是诞生了这篇文章! 善良的我选择帮助别人 可能是网上关于 G ...
- Android开发之去掉listview的点击效果,一行代码间接粗暴,解决你的问题。
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之去掉listview的点击效果,一行代码间接粗暴,解决你的问题. 当你在用list ...
- 自定义一个更好用的SwipeRefreshLayout(弹力拉伸效果详解)(转载)
转自: 自定义一个更好用的SwipeRefreshLayout(弹力拉伸效果详解) 前言 熟悉SwipeRefreshLayout的同学一定知道,SwipeRefreshLayout是android里 ...
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 2012-04-25 16:29:04| 分类: 学习 |字号 订阅 在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE ...
- 【原】iOS动态性(四):一行代码实现iOS序列化与反序列化(runtime)
为取得更好的排版效果,本文同样发布在简书上,强烈建议跳转到[1]http://www.jianshu.com/p/fed1dcb1ac9f 一.变量声明 为便于下文讨论,提前创建父类Biology以及 ...
随机推荐
- 论SOA架构的几种主要开发方式【转】
面向服务架构soa以其独特的优势越来越受到企业的重视,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署.组合和使用.服务层是SOA的基础,可以直接被应用调用,从而有效控制系 ...
- leetcode 二分查找
https://oj.leetcode.com/problems/search-for-a-range/就是一个二分查找,没事练练手 public class Solution { public in ...
- bzoj 3226 [Sdoi2008]校门外的区间(线段树)
3226: [Sdoi2008]校门外的区间 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 615 Solved: 227[Submit][Stat ...
- JavaScript高级程序设计39.pdf
第13章 事件 JavaScript与HTML之间的交互式通过事件来实现的. 事件流 事件流描述的是从页面中接收事件的顺序,IE和Netscape提出了完全相反的事件流概念,IE是事件冒泡流,Nets ...
- 你为什么学MSP430
很清楚,很明白,目的性极强,你学这个,是为了竞赛,学51也是,学习FPGA也是,你压根打心眼里就没打算走硬件方向,原因不多说,尽管你还是喜欢硬件的,但是,现实是,一个人的精力是有限的,你啊,好好弄好你 ...
- hdoj 2035 人见人爱A^B
人见人爱A^B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- tar打包和解压命令
如果你有一个大文件 想下载下来 但是又太大 可以压缩一下 然后打包 #压缩 tar -czvf ***.tar.gz tar -cjvf ***.tar.bz2 #解压缩 tar -xzvf ***. ...
- java中如何使正在运行中的线程退出
终止线程的三种方法 有三种方法可以使终止线程. 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2. 使用stop方法强行终止线程(这个方法不 ...
- (5/18)重学Standford_iOS7开发_视图控制器生命周期_课程笔记
第五课: 1.UITextView @property (nonatomic, readonly) NSTextStorage *textStorage;//注意为只读属性,因此不能直接更改内容,NS ...
- linux 环境下java环境配置
vi + /etc/profile向文件里面追加以下内容:JAVA_HOME=/usr/local/java7JRE_HOME=/usr/local/java7/jrePATH=$PATH:$JAVA ...