zoukankan      html  css  js  c++  java
  • UIScrollView增加刷新

    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

  • 相关阅读:
    如何手动卸载 SQL Server 2005 实例
    马大哈的读后感
    CVS提交0KB的文件失败
    confluence权限管理
    关于confluence注册
    建议使用j2ee自带的ant
    cvs log的几个选项说明(b,r HEAD,n,d)
    JIRA与Confluence的安装与集成(4)
    使用命令行调用Beyond Compare进行文件对比
    利用SecureCRT实现Linux编译
  • 原文地址:https://www.cnblogs.com/Kingly/p/5641926.html
Copyright © 2011-2022 走看看