1、

if (!self.scrollView) {

CGRect frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame));

UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:frame];

//增加这个滚动事件是为了执行BaseViewController中的scrollViewDidEndDragging事件,滚动立马隐藏键盘

scrollView.delegate = self;

scrollView.backgroundColor = [UIColor clearColor];

[scrollView addHeaderWithTarget:self action:@selector(loadData)];

[self.view addSubview:scrollView];

self.scrollView = scrollView;

//为了让scrollView可以滚动,设置contentSize

self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame) + 10);

} else {

[self.scrollView headerEndRefreshing];

}

------------------------------------------------------------------------------------------------------------

//

//  UIScrollView+MJRefresh.h

//  MJRefreshExample

//

//  Created by MJ Lee on 14-5-28.

//  Copyright (c) 2014年 itcast. All rights reserved.

//

// 版权属于原作者

// http://code4app.com (cn) http://code4app.net (en)

// 发布代码于最专业的源码分享网站: Code4App.com

#import <UIKit/UIKit.h>

@interface UIScrollView (MJRefresh)

#pragma mark - 下拉刷新

/**

*  添加一个下拉刷新头部控件

*

*  @param callback 回调

*/

- (void)addHeaderWithCallback:(void (^)())callback;

/**

*  添加一个下拉刷新头部控件

*

*  @param target 目标

*  @param action 回调方法

*/

- (void)addHeaderWithTarget:(id)target action:(SEL)action;

/**

*  移除下拉刷新头部控件

*/

- (void)removeHeader;

/**

*  主动让下拉刷新头部控件进入刷新状态

*/

- (void)headerBeginRefreshing;

/**

*  让下拉刷新头部控件停止刷新状态

*/

- (void)headerEndRefreshing;

/**

*  下拉刷新头部控件的可见性

*/

@property (nonatomic, assign, getter = isHeaderHidden) BOOL headerHidden;

/**

*  是否正在下拉刷新

*/

@property (nonatomic, assign, readonly, getter = isHeaderRefreshing) BOOL headerRefreshing;

#pragma mark - 上拉刷新

/**

*  添加一个上拉刷新尾部控件

*

*  @param callback 回调

*/

- (void)addFooterWithCallback:(void (^)())callback;

/**

*  添加一个上拉刷新尾部控件

*

*  @param target 目标

*  @param action 回调方法

*/

- (void)addFooterWithTarget:(id)target action:(SEL)action;

/**

*  移除上拉刷新尾部控件

*/

- (void)removeFooter;

/**

*  主动让上拉刷新尾部控件进入刷新状态

*/

- (void)footerBeginRefreshing;

/**

*  让上拉刷新尾部控件停止刷新状态

*/

- (void)footerEndRefreshing;

/**

*  上拉刷新头部控件的可见性

*/

@property (nonatomic, assign, getter = isFooterHidden) BOOL footerHidden;

/**

*  是否正在上拉刷新

*/

@property (nonatomic, assign, readonly, getter = isFooterRefreshing) BOOL footerRefreshing;

/**

*  设置尾部控件的文字

*/

@property (copy, nonatomic) NSString *footerPullToRefreshText; // 默认:@"上拉可以加载更多数据"

@property (copy, nonatomic) NSString *footerReleaseToRefreshText; // 默认:@"松开立即加载更多数据"

@property (copy, nonatomic) NSString *footerRefreshingText; // 默认:@"MJ哥正在帮你加载数据..."

/**

*  设置头部控件的文字

*/

@property (copy, nonatomic) NSString *headerPullToRefreshText; // 默认:@"下拉可以刷新"

@property (copy, nonatomic) NSString *headerReleaseToRefreshText; // 默认:@"松开立即刷新"

@property (copy, nonatomic) NSString *headerRefreshingText; // 默认:@"MJ哥正在帮你刷新..."

@end

--------------------------------------------------------------------

//

//  UIScrollView+MJRefresh.m

//  MJRefreshExample

//

//  Created by MJ Lee on 14-5-28.

//  Copyright (c) 2014年 itcast. All rights reserved.

//

// 版权属于原作者

// http://code4app.com (cn) http://code4app.net (en)

// 发布代码于最专业的源码分享网站: Code4App.com

#import "UIScrollView+MJRefresh.h"

#import "MJRefreshHeaderView.h"

#import "MJRefreshFooterView.h"

#import <objc/runtime.h>

@interface UIScrollView()

@property (weak, nonatomic) MJRefreshHeaderView *header;

@property (weak, nonatomic) MJRefreshFooterView *footer;

@end

@implementation UIScrollView (MJRefresh)

#pragma mark - 运行时相关

static char MJRefreshHeaderViewKey;

static char MJRefreshFooterViewKey;

- (void)setHeader:(MJRefreshHeaderView *)header {

[self willChangeValueForKey:@"MJRefreshHeaderViewKey"];

objc_setAssociatedObject(self, &MJRefreshHeaderViewKey,

header,

OBJC_ASSOCIATION_ASSIGN);

[self didChangeValueForKey:@"MJRefreshHeaderViewKey"];

}

- (MJRefreshHeaderView *)header {

return objc_getAssociatedObject(self, &MJRefreshHeaderViewKey);

}

- (void)setFooter:(MJRefreshFooterView *)footer {

[self willChangeValueForKey:@"MJRefreshFooterViewKey"];

objc_setAssociatedObject(self, &MJRefreshFooterViewKey,

footer,

OBJC_ASSOCIATION_ASSIGN);

[self didChangeValueForKey:@"MJRefreshFooterViewKey"];

}

- (MJRefreshFooterView *)footer {

return objc_getAssociatedObject(self, &MJRefreshFooterViewKey);

}

#pragma mark - 下拉刷新

/**

*  添加一个下拉刷新头部控件

*

*  @param callback 回调

*/

- (void)addHeaderWithCallback:(void (^)())callback

{

// 1.创建新的header

if (!self.header) {

MJRefreshHeaderView *header = [MJRefreshHeaderView header];

[self addSubview:header];

self.header = header;

}

// 2.设置block回调

self.header.beginRefreshingCallback = callback;

}

/**

*  添加一个下拉刷新头部控件

*

*  @param target 目标

*  @param action 回调方法

*/

- (void)addHeaderWithTarget:(id)target action:(SEL)action

{

// 1.创建新的header

if (!self.header) {

MJRefreshHeaderView *header = [MJRefreshHeaderView header];

[self addSubview:header];

self.header = header;

}

// 2.设置目标和回调方法

self.header.beginRefreshingTaget = target;

self.header.beginRefreshingAction = action;

}

/**

*  移除下拉刷新头部控件

*/

- (void)removeHeader

{

[self.header removeFromSuperview];

self.header = nil;

}

/**

*  主动让下拉刷新头部控件进入刷新状态

*/

- (void)headerBeginRefreshing

{

[self.header beginRefreshing];

}

/**

*  让下拉刷新头部控件停止刷新状态

*/

- (void)headerEndRefreshing

{

[self.header endRefreshing];

}

/**

*  下拉刷新头部控件的可见性

*/

- (void)setHeaderHidden:(BOOL)hidden

{

self.header.hidden = hidden;

}

- (BOOL)isHeaderHidden

{

return self.header.isHidden;

}

- (BOOL)isHeaderRefreshing

{

return self.header.state == MJRefreshStateRefreshing;

}

#pragma mark - 上拉刷新

/**

*  添加一个上拉刷新尾部控件

*

*  @param callback 回调

*/

- (void)addFooterWithCallback:(void (^)())callback

{

// 1.创建新的footer

if (!self.footer) {

MJRefreshFooterView *footer = [MJRefreshFooterView footer];

[self addSubview:footer];

self.footer = footer;

}

// 2.设置block回调

self.footer.beginRefreshingCallback = callback;

}

/**

*  添加一个上拉刷新尾部控件

*

*  @param target 目标

*  @param action 回调方法

*/

- (void)addFooterWithTarget:(id)target action:(SEL)action

{

// 1.创建新的footer

if (!self.footer) {

MJRefreshFooterView *footer = [MJRefreshFooterView footer];

[self addSubview:footer];

self.footer = footer;

}

// 2.设置目标和回调方法

self.footer.beginRefreshingTaget = target;

self.footer.beginRefreshingAction = action;

}

/**

*  移除上拉刷新尾部控件

*/

- (void)removeFooter

{

[self.footer removeFromSuperview];

self.footer = nil;

}

/**

*  主动让上拉刷新尾部控件进入刷新状态

*/

- (void)footerBeginRefreshing

{

[self.footer beginRefreshing];

}

/**

*  让上拉刷新尾部控件停止刷新状态

*/

- (void)footerEndRefreshing

{

[self.footer endRefreshing];

}

/**

*  下拉刷新头部控件的可见性

*/

- (void)setFooterHidden:(BOOL)hidden

{

self.footer.hidden = hidden;

}

- (BOOL)isFooterHidden

{

return self.footer.isHidden;

}

- (BOOL)isFooterRefreshing

{

return self.footer.state == MJRefreshStateRefreshing;

}

/**

*  文字

*/

- (void)setFooterPullToRefreshText:(NSString *)footerPullToRefreshText

{

self.footer.pullToRefreshText = footerPullToRefreshText;

}

- (NSString *)footerPullToRefreshText

{

return self.footer.pullToRefreshText;

}

- (void)setFooterReleaseToRefreshText:(NSString *)footerReleaseToRefreshText

{

self.footer.releaseToRefreshText = footerReleaseToRefreshText;

}

- (NSString *)footerReleaseToRefreshText

{

return self.footer.releaseToRefreshText;

}

- (void)setFooterRefreshingText:(NSString *)footerRefreshingText

{

self.footer.refreshingText = footerRefreshingText;

}

- (NSString *)footerRefreshingText

{

return self.footer.refreshingText;

}

- (void)setHeaderPullToRefreshText:(NSString *)headerPullToRefreshText

{

self.header.pullToRefreshText = headerPullToRefreshText;

}

- (NSString *)headerPullToRefreshText

{

return self.header.pullToRefreshText;

}

- (void)setHeaderReleaseToRefreshText:(NSString *)headerReleaseToRefreshText

{

self.header.releaseToRefreshText = headerReleaseToRefreshText;

}

- (NSString *)headerReleaseToRefreshText

{

return self.header.releaseToRefreshText;

}

- (void)setHeaderRefreshingText:(NSString *)headerRefreshingText

{

self.header.refreshingText = headerRefreshingText;

}

- (NSString *)headerRefreshingText

{

return self.header.refreshingText;

}

@end

---------------------------------------------------------------------------

//

//  MJRefreshHeaderView.h

//  MJRefresh

//

//  Created by mj on 13-2-26.

//  Copyright (c) 2013年 itcast. All rights reserved.

//  下拉刷新

// 版权属于原作者

// http://code4app.com (cn) http://code4app.net (en)

// 发布代码于最专业的源码分享网站: Code4App.com

#import "MJRefreshBaseView.h"

@interface MJRefreshHeaderView : MJRefreshBaseView

+ (instancetype)header;

@end

--------------------------------------------------------------

//

//  MJRefreshHeaderView.m

//  MJRefresh

//

//  Created by mj on 13-2-26.

//  Copyright (c) 2013年 itcast. All rights reserved.

//  下拉刷新

// 版权属于原作者

// http://code4app.com (cn) http://code4app.net (en)

// 发布代码于最专业的源码分享网站: Code4App.com

#import "MJRefreshConst.h"

#import "MJRefreshHeaderView.h"

#import "UIView+MJExtension.h"

#import "UIScrollView+MJExtension.h"

@interface MJRefreshHeaderView()

// 最后的更新时间

@property (nonatomic, strong) NSDate *lastUpdateTime;

@property (nonatomic, weak) UILabel *lastUpdateTimeLabel;

@end

@implementation MJRefreshHeaderView

#pragma mark - 控件初始化

/**

*  时间标签

*/

- (UILabel *)lastUpdateTimeLabel

{

if (!_lastUpdateTimeLabel) {

// 1.创建控件

UILabel *lastUpdateTimeLabel = [[UILabel alloc] init];

lastUpdateTimeLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;

lastUpdateTimeLabel.font = [UIFont boldSystemFontOfSize:12];

lastUpdateTimeLabel.textColor = MJRefreshLabelTextColor;

lastUpdateTimeLabel.backgroundColor = [UIColor clearColor];

lastUpdateTimeLabel.textAlignment = NSTextAlignmentCenter;

[self addSubview:_lastUpdateTimeLabel = lastUpdateTimeLabel];

// 2.加载时间

self.lastUpdateTime = [[NSUserDefaults standardUserDefaults] objectForKey:MJRefreshHeaderTimeKey];

}

return _lastUpdateTimeLabel;

}

+ (instancetype)header

{

return [[MJRefreshHeaderView alloc] init];

}

- (id)initWithFrame:(CGRect)frame

{

if (self = [super initWithFrame:frame]) {

self.pullToRefreshText = MJRefreshHeaderPullToRefresh;

self.releaseToRefreshText = MJRefreshHeaderReleaseToRefresh;

self.refreshingText = MJRefreshHeaderRefreshing;

}

return self;

}

- (void)layoutSubviews

{

[super layoutSubviews];

CGFloat statusX = 0;

CGFloat statusY = 0;

CGFloat statusHeight = self.mj_height * 0.5;

CGFloat statusWidth = self.mj_width;

// 1.状态标签

self.statusLabel.frame = CGRectMake(statusX, statusY, statusWidth, statusHeight);

// 2.时间标签

CGFloat lastUpdateY = statusHeight;

CGFloat lastUpdateX = 0;

CGFloat lastUpdateHeight = statusHeight;

CGFloat lastUpdateWidth = statusWidth;

self.lastUpdateTimeLabel.frame = CGRectMake(lastUpdateX, lastUpdateY, lastUpdateWidth, lastUpdateHeight);

}

- (void)willMoveToSuperview:(UIView *)newSuperview

{

[super willMoveToSuperview:newSuperview];

// 设置自己的位置和尺寸

self.mj_y = - self.mj_height;

}

#pragma mark - 状态相关

#pragma mark 设置最后的更新时间

- (void)setLastUpdateTime:(NSDate *)lastUpdateTime

{

_lastUpdateTime = lastUpdateTime;

// 1.归档

[[NSUserDefaults standardUserDefaults] setObject:lastUpdateTime forKey:MJRefreshHeaderTimeKey];

[[NSUserDefaults standardUserDefaults] synchronize];

// 2.更新时间

[self updateTimeLabel];

}

#pragma mark 更新时间字符串

- (void)updateTimeLabel

{

if (!self.lastUpdateTime) return;

// 1.获得年月日

NSCalendar *calendar = [NSCalendar currentCalendar];

NSUInteger unitFlags = NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit |NSHourCalendarUnit |NSMinuteCalendarUnit;

NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:_lastUpdateTime];

NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]];

// 2.格式化日期

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

if ([cmp1 day] == [cmp2 day]) { // 今天

formatter.dateFormat = @"今天 HH:mm";

} else if ([cmp1 year] == [cmp2 year]) { // 今年

formatter.dateFormat = @"MM-dd HH:mm";

} else {

formatter.dateFormat = @"yyyy-MM-dd HH:mm";

}

NSString *time = [formatter stringFromDate:self.lastUpdateTime];

// 3.显示日期

self.lastUpdateTimeLabel.text = [NSString stringWithFormat:@"最后更新:%@", time];

}

#pragma mark - 监听UIScrollView的contentOffset属性

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

// 不能跟用户交互就直接返回

if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden) return;

// 如果正在刷新,直接返回

if (self.state == MJRefreshStateRefreshing) return;

if ([MJRefreshContentOffset isEqualToString:keyPath]) {

[self adjustStateWithContentOffset];

}

}

/**

*  调整状态

*/

- (void)adjustStateWithContentOffset

{

// 当前的contentOffset

CGFloat currentOffsetY = self.scrollView.mj_contentOffsetY;

// 头部控件刚好出现的offsetY

CGFloat happenOffsetY = - self.scrollViewOriginalInset.top;

// 如果是向上滚动到看不见头部控件,直接返回

if (currentOffsetY >= happenOffsetY) return;

if (self.scrollView.isDragging) {

// 普通 和 即将刷新 的临界点

CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_height;

if (self.state == MJRefreshStateNormal && currentOffsetY < normal2pullingOffsetY) {

// 转为即将刷新状态

self.state = MJRefreshStatePulling;

} else if (self.state == MJRefreshStatePulling && currentOffsetY >= normal2pullingOffsetY) {

// 转为普通状态

self.state = MJRefreshStateNormal;

}

} else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开

// 开始刷新

self.state = MJRefreshStateRefreshing;

}

}

#pragma mark 设置状态

- (void)setState:(MJRefreshState)state

{

// 1.一样的就直接返回

if (self.state == state) return;

// 2.保存旧状态

MJRefreshState oldState = self.state;

// 3.调用父类方法

[super setState:state];

// 4.根据状态执行不同的操作

switch (state) {

case MJRefreshStateNormal: // 下拉可以刷新

{

// 刷新完毕

if (MJRefreshStateRefreshing == oldState) {

self.arrowImage.transform = CGAffineTransformIdentity;

// 保存刷新时间

self.lastUpdateTime = [NSDate date];

[UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{

self.scrollView.mj_contentInsetTop -= self.mj_height;

}];

} else {

// 执行动画

[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{

self.arrowImage.transform = CGAffineTransformIdentity;

}];

}

break;

}

case MJRefreshStatePulling: // 松开可立即刷新

{

// 执行动画

[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{

self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI);

}];

break;

}

case MJRefreshStateRefreshing: // 正在刷新中

{

// 执行动画

[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{

// 1.增加滚动区域

CGFloat top = self.scrollViewOriginalInset.top + self.mj_height;

self.scrollView.mj_contentInsetTop = top;

// 2.设置滚动位置

self.scrollView.mj_contentOffsetY = - top;

}];

break;

}

default:

break;

}

}

@end

UIScrollView增加刷新的更多相关文章

  1. UIScrollView增加回弹效果

    项目中经常要增加上下滑动回弹的效果: self.scrollView.alwaysBounceVertical = YES;

  2. 在UIScrollView、UICollectionView和UITableView中添加UIRefreshControl实现下拉刷新

    Apple在iOS 6中添加了UIRefreshControl,但只能在UITableViewController中使用,不能在UIScrollView和UICollectionView中使用. 从i ...

  3. iOS - UIScrollView 相关属性代理详解

    一.UIScrollView的属性和代理方法详解 属性: - (void)viewDidLoad { [super viewDidLoad]; _scrollView.backgroundColor ...

  4. 如何写一套下拉刷新的控件?《MJRefresh原理浅析》(附Demo下载地址)

    相信大家有很多人在做项目的时候都在使用MJRefresh 控件来实现下拉刷新的功能: MJRefresh经过不断的重构与更新迭代,现在不管是功能上还是代码结构上都是相当不错的,都是很值我们去学习的. ...

  5. iOS开发UI篇—UIScrollView控件介绍

    iOS开发UI篇—UIScrollView控件介绍 一.知识点简单介绍 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限 ...

  6. 利用less监视模式实时预览样式刷新浏览器

    [前言]此处介绍的方法只是我个人的用法,相信大家有更好更简洁的方式. 上次写到利用LiveReload解放F5.而且LiveReload可以编辑sass/less/stylus.但是可惜发现LiveR ...

  7. iOS开发之 UIScrollView的frame、contentSize、contentOffset和contentInset属性

    ios中下拉图片变大效果 http://blog.csdn.net/mad2man/article/details/14169197 IOS中UIScrollView的frame.contentSiz ...

  8. UIScrollView控件详解

    一.知识点简单介绍 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限 (2)当展⽰示的内容较多,超出⼀一个屏幕时,⽤用户可 ...

  9. IOS UI-滚动视图(UIScrollView)

    #import "ViewController.h" /* 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤小是极其有限的,因此直接展示在⽤用户眼前的内容也相当有限 ...

随机推荐

  1. 【Android】中兴ZTE sdcard路径的问题

    测试机: ZTE U950 现象: 用Environment.getExternalStorageDirectory()取到的路径是/mnt/sdcard 真相: /mnt/sdcard/是一个空文件 ...

  2. iOS集成ijkplayer视频直播框架,遇到的bug和坑...

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 32.0px "Helvetica Neue"; color: #555555 } p. ...

  3. MVC中的时间js格式化

    记录下我遇到的一个,MVC中post请求返回一个JSON字符串,其中包含数据库中的时间格式(如:/Date(10000000000)/),不知道怎么处理.百度的方法都不适用,经自己研究,做成了一个Jq ...

  4. VS2015 Git 插件使用教程

    VS2015 中继承了 Git 插件,再也不用下载 Github for Windows了. 从 团队-管理连接  中打开 团队资源管理器 克隆Repository 在 本地 Git 存储库下面点击 ...

  5. MySql技巧个人笔记

    1.数据null时sum的用法 mysql数据库SUM(A+B)不一定等于SUM(A)+SUM(B),当A或B为NULL时,SUM(A+B)=NULL. 2.or改为in 同一字段,将or改写为in( ...

  6. 中控考勤仪IFace302多线程操作时无法订阅事件

    场景: 在各办事点安装中控考勤仪Iface302,各办事点的工作人员上下班报到时使用指纹或面纹进行自动登记,验证成功后将与服务吕进行通讯记录相关的考勤信息. 条件限制: 由于Iface302设备不支持 ...

  7. 十五天精通WCF——第十天 学会用SvcConfigEditor来简化配置

    我们在玩wcf项目的时候,都是自己手工编写system.serviceModel下面的配置,虽然在webconfig中做wcf的服务配置的时候,vs提供大多 数的代码提示,但对于不太熟悉服务配置的小鸟 ...

  8. Linux JDK 安装

    1,下载JDK(Linux版) 官网下载:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2,  建立java目录 ...

  9. shell流程控制&函数

    条件 if-then-elif-then-fi if的条件部分经常使用test EXPRESSION或[ EXPRESSION ]实现,test的用法可以参见test if 条件1 #if 条件1;t ...

  10. x01.os.6: 8086 指令

    M:存储器A:累加器R:寄存器SEGR:段寄存器IMM:立即数X:标志位状态依运算或操作结果而定U:相应标志位未定义-:不影响 数据传送指令 时钟数 访问次数 字节数 对标志位影响 指令意义 MOV ...