欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS下拉、上拉刷新控件的封裝

 更新時間:2019年04月28日 10:04:49   作者:hero_wqb  
這篇文章主要為大家詳細(xì)介紹了iOS下拉、上拉刷新控件的封裝,具有一定的參考價值,感興趣的小伙伴們可以參考一下

iOS 封裝下拉、上拉刷新控件,首先看下效果圖:

簡單闡述一下:自定義頭部、尾部刷新視圖,繼承UIView,通過KVO監(jiān)聽scrollView的滑動,通過偏移量設(shè)置刷新狀態(tài),通過修改狀態(tài)修改scrollView的滾動位置。建一個UIScrollView的分類,添加上拉、下拉刷新及回調(diào)的方法,可以讓UITableView、UICollectionView直接調(diào)用?,F(xiàn)在很多應(yīng)用是在滑動到底部自動進(jìn)行上拉加載超做,可以在scrollViewDidScroll這個代理方法中手動調(diào)用尾部刷新。

下面貼上主要相關(guān)代碼:

控制器ViewController:

#import <UIKit/UIKit.h>
 
@interface ViewController : UIViewController
 
@end
 
/*** ---------------分割線--------------- ***/
 
#import "ViewController.h"
#import "HWRefresh.h"
 
@interface ViewController ()<UITableViewDataSource, UITableViewDelegate>
 
@property (nonatomic, strong) NSMutableArray *array;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, assign) NSInteger page;
 
@end
 
@implementation ViewController
 
- (NSMutableArray *)array
{
 if (!_array) {
  _array = [NSMutableArray array];
 }
 
 return _array;
}
 
- (void)viewDidLoad {
 [super viewDidLoad];
 
 self.view.backgroundColor = [UIColor blackColor];
 self.page = 1;
 
 //模擬獲取信息
 [self getInfo];
 
 //創(chuàng)建控件
 [self creatControl];
 
 //添加頭部刷新
 [self addHeaderRefresh];
 
 //添加尾部刷新
 [self addFooterRefresh];
}
 
- (void)getInfo
{
 NSArray *array = @[@"iOS HERO博客", @"iOS HERO博客", @"iOS HERO博客", @"iOS HERO博客", @"http://blog.csdn.net/hero_wqb"];
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  if (self.page == 1) {
   self.array = [NSMutableArray arrayWithArray:array];
  }else{
   [self.array addObjectsFromArray:array];
  }
  [_tableView reloadData];
  [_tableView headerEndRefreshing];
  [_tableView footerEndRefreshing];
  NSLog(@"已經(jīng)刷新好了");
 });
}
 
- (void)creatControl
{
 //列表視圖
 _tableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 64, [[UIScreen mainScreen] bounds].size.width - 100, [[UIScreen mainScreen] bounds].size.height - 164) style:UITableViewStylePlain];
 _tableView.dataSource = self;
 _tableView.delegate = self;
 [self.view addSubview:_tableView];
}
 
- (void)addHeaderRefresh
{
 __weak typeof(self) weakSelf = self;
 [_tableView addHeaderRefreshWithCallback:^{
  __strong typeof(weakSelf) strongSelf = weakSelf;
  strongSelf.page = 1;
  [strongSelf getInfo];
 }];
}
 
- (void)addFooterRefresh
{
 __weak typeof(self) weakSelf = self;
 [_tableView addFooterRefreshWithCallback:^{
  __strong typeof(weakSelf) strongSelf = weakSelf;
  strongSelf.page ++;
  [strongSelf getInfo];
 }];
}
 
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
 return self.array.count;
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *identifier = @"refreshTest";
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
 if (!cell) {
  cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
 }
 cell.textLabel.text = [_array[indexPath.row] stringByAppendingString:[NSString stringWithFormat:@"_%ld", indexPath.row]];
 
 return cell;
}
 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
 //滑動到底部自動刷新
 if (_tableView.contentSize.height > _tableView.frame.size.height && _tableView.contentOffset.y + _tableView.frame.size.height > _tableView.contentSize.height - 40 && _page < 50) {
  [_tableView footerBeginRefreshing];
 }
}
 
@end

刷新基類HWRefreshBaseView:

#import <UIKit/UIKit.h>
 
#define HWRefreshContentOffset @"contentOffset"
 
typedef enum {
 HWRefreshStateNormal = 0, //普通狀態(tài)
 HWRefreshStatePulling,  //釋放即可刷新的狀態(tài)
 HWRefreshStateRefreshing, //正在刷新中的狀態(tài)
} HWRefreshState;
 
@interface HWRefreshBaseView : UIView
 
@property (nonatomic, weak) UIScrollView *scrollView;
@property (nonatomic, copy) NSString *pullToRefreshText;
@property (nonatomic, copy) NSString *releaseToRefreshText;
@property (nonatomic, copy) NSString *refreshingText;
@property (nonatomic, copy) void (^refreshingCallback)();
@property (nonatomic, assign) HWRefreshState state;
@property (nonatomic, assign) UIEdgeInsets scrollViewOriginalInset;
 
- (void)beginRefreshing;
- (void)endRefreshing;
 
@end
 
/*** ---------------分割線--------------- ***/
 
#import "HWRefreshBaseView.h"
 
#define KHWRefreshViewHeight 44.0f
#define KImageW 30.0f
#define KLabelW 100.0f
 
@interface HWRefreshBaseView ()
 
@property (nonatomic, weak) UILabel *rLabel;
@property (nonatomic, weak) UIImageView *rImageView;
 
@end
 
@implementation HWRefreshBaseView
 
- (instancetype)initWithFrame:(CGRect)frame
{
 frame.size.height = KHWRefreshViewHeight;
 if (self = [super initWithFrame:frame]) {
  CGFloat imageH = 30.f;
  CGFloat labelH = 20.f;
  CGFloat imageX = ([UIScreen mainScreen].bounds.size.width - KImageW - KLabelW) * 0.5;
  CGFloat imageY = (KHWRefreshViewHeight - imageH) * 0.5;
  CGFloat labelY = (KHWRefreshViewHeight - labelH) * 0.5;
  
  //圖片
  UIImageView *rImageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, KImageW, imageH)];
  rImageView.image = [UIImage imageNamed:@"refreshing.jpg"];
  [self addSubview:rImageView];
  self.rImageView = rImageView;
  
  //標(biāo)簽
  UILabel *rLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(rImageView.frame), labelY, KLabelW, labelH)];
  rLabel.text = self.pullToRefreshText;
  rLabel.font = [UIFont systemFontOfSize:14.0f];
  rLabel.textAlignment = NSTextAlignmentCenter;
  [self addSubview:rLabel];
  self.rLabel = rLabel;
 }
 
 return self;
}
 
- (void)willMoveToSuperview:(UIView *)newSuperview
{
 [super willMoveToSuperview:newSuperview];
 
 //舊的父控件
 [self.superview removeObserver:self forKeyPath:HWRefreshContentOffset context:nil];
 
 //新的父控件
 if (newSuperview) {
  [newSuperview addObserver:self forKeyPath:HWRefreshContentOffset options:NSKeyValueObservingOptionNew context:nil];
  
  //記錄UIScrollView
  _scrollView = (UIScrollView *)newSuperview;
  
  //記錄UIScrollView最開始的contentInset
  _scrollViewOriginalInset = _scrollView.contentInset;
 }
 
 //居中顯示圖片、提示信息
 CGRect temFrame = _rImageView.frame;
 temFrame.origin.x = (newSuperview.frame.size.width - KImageW - KLabelW) * 0.5;
 _rImageView.frame = temFrame;
 
 CGRect tf = _rLabel.frame;
 tf.origin.x = CGRectGetMaxX(_rImageView.frame);
 _rLabel.frame = tf;
}
 
- (void)setPullToRefreshText:(NSString *)pullToRefreshText
{
 _pullToRefreshText = pullToRefreshText;
 
 self.rLabel.text = pullToRefreshText;
}
 
- (void)setState:(HWRefreshState)state
{
 if (_state == state) return;
 
 switch (state) {
  case HWRefreshStateNormal: {
   [self stopAnimating];
   self.rLabel.text = self.pullToRefreshText;
   break;
  }
   
  case HWRefreshStatePulling: {
   self.rLabel.text = self.releaseToRefreshText;
   break;
  }
   
  case HWRefreshStateRefreshing: {
   [self startAnimating];
   self.rLabel.text = self.refreshingText;
   if (self.refreshingCallback) self.refreshingCallback();
   break;
  }
   
  default:
   break;
 }
 
 _state = state;
}
 
//開始刷新
- (void)beginRefreshing
{
 self.state = HWRefreshStateRefreshing;
}
 
//結(jié)束刷新
- (void)endRefreshing
{
 self.state = HWRefreshStateNormal;
}
 
//開始動畫
- (void)startAnimating
{
 NSMutableArray *array = [NSMutableArray array];
 for (int i = 0; i < 2; i++) {
  NSString *imageName = [NSString stringWithFormat:@"refreshing%02d.jpg", i + 1];
  UIImage *image = [UIImage imageNamed:imageName];
  [array addObject:image];
 }
 
 [_rImageView setAnimationImages:array];
 [_rImageView setAnimationDuration:0.3f];
 [_rImageView startAnimating];
}
 
//結(jié)束動畫
- (void)stopAnimating
{
 if (_rImageView.isAnimating) {
  [_rImageView stopAnimating];
  [_rImageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:0];
 }
}
 
@end

頭部刷新HWRefreshHeader:

#import "HWRefreshBaseView.h"
 
@interface HWRefreshHeader : HWRefreshBaseView
 
+ (instancetype)header;
 
@end
 
/*** ---------------分割線--------------- ***/
 
#import "HWRefreshHeader.h"
 
@implementation HWRefreshHeader
 
+ (instancetype)header
{
 return [[HWRefreshHeader alloc] init];
}
 
- (instancetype)initWithFrame:(CGRect)frame
{
 if (self = [super initWithFrame:frame]) {
  self.pullToRefreshText = @"下拉即可刷新";
  self.releaseToRefreshText = @"釋放即可刷新";
  self.refreshingText = @"刷新中...";
 }
 
 return self;
}
 
- (void)willMoveToSuperview:(UIView *)newSuperview
{
 [super willMoveToSuperview:newSuperview];
 
 //設(shè)置自己的位置和尺寸
 CGRect frame = self.frame;
 frame.origin.y = - self.frame.size.height;
 self.frame = frame;
}
 
 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
 //不能跟用戶交互或正在刷新就直接返回
 if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden || self.state == HWRefreshStateRefreshing) return;
 
 //根據(jù)偏移量設(shè)置相應(yīng)狀態(tài)
 if ([keyPath isEqualToString:HWRefreshContentOffset]) {
  [self setStateWithContentOffset];
 }
}
 
- (void)setStateWithContentOffset
{
 //當(dāng)前的contentOffset
 CGFloat currentOffsetY = self.scrollView.contentOffset.y;
 
 //頭部控件剛好出現(xiàn)的offsetY
 CGFloat happenOffsetY = - self.scrollViewOriginalInset.top;
 
 //如果是向上滾動到看不見頭部控件,直接返回
 if (currentOffsetY >= happenOffsetY) return;
 
 //滑動時
 if (self.scrollView.isDragging) {
  //普通狀態(tài)和即將刷新狀態(tài)的臨界點
  CGFloat normalTopullingOffsetY = happenOffsetY - self.frame.size.height;
  
  //轉(zhuǎn)為即將刷新狀態(tài)
  if (self.state == HWRefreshStateNormal && currentOffsetY < normalTopullingOffsetY) {
   self.state = HWRefreshStatePulling;
   
  //轉(zhuǎn)為普通狀態(tài)
  }else if (self.state == HWRefreshStatePulling && currentOffsetY >= normalTopullingOffsetY) {
   self.state = HWRefreshStateNormal;
  }
  
 //松手時,如果是松開就可以進(jìn)行刷新的狀態(tài),則進(jìn)行刷新
 }else if (self.state == HWRefreshStatePulling) {
  self.state = HWRefreshStateRefreshing;
 }
}
 
- (void)setState:(HWRefreshState)state
{
 //若狀態(tài)未改變,直接返回
 if (self.state == state) return;
 
 //保存舊狀態(tài)
 HWRefreshState oldState = self.state;
 
 //調(diào)用父類方法
 [super setState:state];
 
 switch (state) {
  case HWRefreshStateNormal: {
   //如果由刷新狀態(tài)返回到普通狀態(tài)
   if (oldState == HWRefreshStateRefreshing) {
    [UIView animateWithDuration:0.25f animations:^{
     UIEdgeInsets inset = self.scrollView.contentInset;
     inset.top -= self.frame.size.height;
     self.scrollView.contentInset = inset;
    }];
   }
   break;
  }
   
  case HWRefreshStatePulling: {
   break;
  }
   
  case HWRefreshStateRefreshing: {
   //執(zhí)行動畫
   [UIView animateWithDuration:0.25f animations:^{
    CGFloat top = self.scrollViewOriginalInset.top + self.frame.size.height;
    
    //增加滾動區(qū)域
    UIEdgeInsets inset = self.scrollView.contentInset;
    inset.top = top;
    self.scrollView.contentInset = inset;
    
    //設(shè)置滾動位置
    CGPoint offset = self.scrollView.contentOffset;
    offset.y = - top;
    self.scrollView.contentOffset = offset;
   }];
   break;
  }
   
  default:
   break;
 }
 
 self.state = state;
}
 
@end

分類UIScrollView+HWRefresh:

#import <UIKit/UIKit.h>
 
@interface UIScrollView (HWRefresh)
 
//添加下拉刷新回調(diào)
- (void)addHeaderRefreshWithCallback:(void (^)())callback;
 
//讓下拉刷新控件停止刷新
- (void)headerEndRefreshing;
 
//添加上拉刷新回調(diào)
- (void)addFooterRefreshWithCallback:(void (^)())callback;
 
//讓上拉刷新控件開始刷新
- (void)footerBeginRefreshing;
 
//讓上拉刷新控件停止刷新
- (void)footerEndRefreshing;
 
@end
 
/*** ---------------分割線--------------- ***/
 
#import "UIScrollView+HWRefresh.h"
#import "HWRefreshHeader.h"
#import "HWRefreshFooter.h"
#import <objc/runtime.h>
 
@interface UIScrollView ()
 
@property (nonatomic, weak) HWRefreshHeader *header;
@property (weak, nonatomic) HWRefreshFooter *footer;
 
@end
 
@implementation UIScrollView (HWRefresh)
 
static char HWRefreshHeaderKey;
static char HWRefreshFooterKey;
 
- (void)setHeader:(HWRefreshHeader *)header
{
 [self willChangeValueForKey:@"HWRefreshHeaderKey"];
 objc_setAssociatedObject(self, &HWRefreshHeaderKey, header, OBJC_ASSOCIATION_ASSIGN);
 [self didChangeValueForKey:@"HWRefreshHeaderKey"];
}
 
- (HWRefreshHeader *)header
{
 return objc_getAssociatedObject(self, &HWRefreshHeaderKey);
}
 
- (void)setFooter:(HWRefreshFooter *)footer
{
 [self willChangeValueForKey:@"HWRefreshFooterKey"];
 objc_setAssociatedObject(self, &HWRefreshFooterKey, footer, OBJC_ASSOCIATION_ASSIGN);
 [self didChangeValueForKey:@"HWRefreshFooterKey"];
}
 
- (HWRefreshFooter *)footer
{
 return objc_getAssociatedObject(self, &HWRefreshFooterKey);
}
 
- (void)addHeaderRefreshWithCallback:(void (^)())callback
{
 if (!self.header) {
  HWRefreshHeader *header = [HWRefreshHeader header];
  [self addSubview:header];
  self.header = header;
 }
 
 self.header.refreshingCallback = callback;
}
 
- (void)headerEndRefreshing
{
 [self.header endRefreshing];
}
 
- (void)addFooterRefreshWithCallback:(void (^)())callback
{
 if (!self.footer) {
  HWRefreshFooter *footer = [HWRefreshFooter footer];
  [self addSubview:footer];
  self.footer = footer;
 }
 
 self.footer.refreshingCallback = callback;
}
 
- (void)footerBeginRefreshing
{
 [self.footer beginRefreshing];
}
 
- (void)footerEndRefreshing
{
 [self.footer endRefreshing];
}
 
@end

Demo下載鏈接

寫博客的初心是希望大家共同交流成長,博主水平有限難免有偏頗之處,歡迎批評指正。

相關(guān)文章

  • iOS驗證手機號的正則表達(dá)式

    iOS驗證手機號的正則表達(dá)式

    這篇文章主要為大家詳細(xì)介紹了iOS驗證手機號的正則表達(dá)式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 解析Objective-C?中?`+load`?方法的執(zhí)行順序

    解析Objective-C?中?`+load`?方法的執(zhí)行順序

    在?Objective-C?中,+load?方法是在類或分類被加載到內(nèi)存時調(diào)用的,它在程序啟動過程中非常早的階段執(zhí)行,用于在類或分類被加載時進(jìn)行一些初始化工作,這篇文章主要介紹了?Objective-C?中?`+load`?方法的執(zhí)行順序,需要的朋友可以參考下
    2024-07-07
  • 在iOS App中實現(xiàn)地理位置定位的基本方法解析

    在iOS App中實現(xiàn)地理位置定位的基本方法解析

    這篇文章主要介紹了在iOS App中實現(xiàn)地理位置定位的基本方法解析,包括獲取當(dāng)前位置和計算兩點間距離等基本功能的實現(xiàn),需要的朋友可以參考下
    2016-05-05
  • iOS中你需要的彈窗效果總結(jié)大全

    iOS中你需要的彈窗效果總結(jié)大全

    彈窗是app中常見控件之一,一般由于項目需求,我們很少能直接使用系統(tǒng)提供的彈窗,這個時候就需要我們根據(jù)產(chǎn)品需求封裝自定義彈窗了。下面這篇文章主要給大家介紹了關(guān)于iOS中你需要的彈窗效果的相關(guān)資料,需要的朋友可以參考下
    2018-09-09
  • iOS App開發(fā)中使用及自定義UITableViewCell的教程

    iOS App開發(fā)中使用及自定義UITableViewCell的教程

    這篇文章主要介紹了iOS App開發(fā)中使用及自定義UITableViewCell的教程,自定義TableViewCell文中使用Objective-C演示而非ib,需要的朋友可以參考下
    2016-04-04
  • iOS如何獲取手機的Mac地址

    iOS如何獲取手機的Mac地址

    這篇文章主要為大家詳細(xì)介紹了iOS獲取手機的Mac地址的多種方法,感興趣的小伙伴們可以參考一下
    2016-04-04
  • iOS中常見的視圖和圖片處理示例詳解

    iOS中常見的視圖和圖片處理示例詳解

    在日常ios開發(fā)中經(jīng)常會遇到視圖和圖片的處理,下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS中常見的視圖和圖片處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)和工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下。
    2017-10-10
  • iOS開發(fā)之XLForm的使用方法

    iOS開發(fā)之XLForm的使用方法

    這篇文章主要介紹了iOS開發(fā)之XLForm的使用方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • IOS  Swift3 四種單例模式詳解及實例

    IOS Swift3 四種單例模式詳解及實例

    這篇文章主要介紹了IOS Swift3 四種單例模式詳解及實例的相關(guān)資料,這里對四種單例模式進(jìn)行了實例介紹 ,需要的朋友可以參考下
    2016-12-12
  • ios 服務(wù)器端推送證書生成的方法

    ios 服務(wù)器端推送證書生成的方法

    這篇文章主要介紹了ios 服務(wù)器端推送證書生成的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08

最新評論